(Kotlin,viewBinding)java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“boolean java.lang.Thread.isAlive(

Posted

技术标签:

【中文标题】(Kotlin,viewBinding)java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“boolean java.lang.Thread.isAlive()”【英文标题】:(Kotlin, viewBinding) java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Thread.isAlive()' on a null object reference 【发布时间】:2022-01-23 22:53:20 【问题描述】:

我按照 youtube 中的教程使用 kotlin 创建搜索视图。可能的解决方案是什么?活动代码在android studio中没有显示任何错误,但在运行时显示错误。

我在运行时测试时出错

E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Thread.isAlive()' on a null object reference
        at com.github.barteksc.pdfviewer.PDFView.loadComplete(PDFView.java:756)
        at com.github.barteksc.pdfviewer.DecodingAsyncTask.onPostExecute(DecodingAsyncTask.java:80)
        at com.github.barteksc.pdfviewer.DecodingAsyncTask.onPostExecute(DecodingAsyncTask.java:27)
        at android.os.AsyncTask.finish(AsyncTask.java:667)
        at android.os.AsyncTask.-wrap1(AsyncTask.java)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:684)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

这是使用的依赖项

dependencies 

    implementation 'androidx.core:core-ktx:1.7.0'
    implementation 'androidx.appcompat:appcompat:1.4.0'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.2'

    implementation 'com.google.firebase:firebase-analytics-ktx:20.0.2'
    implementation 'com.google.firebase:firebase-auth-ktx:21.0.1'
    implementation 'com.google.firebase:firebase-database-ktx:20.0.3'
    implementation 'com.google.firebase:firebase-storage-ktx:20.0.0'

    //pdf library
    implementation 'com.github.mhiew:android-pdf-viewer:3.2.0-beta.1'


    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

这是 PdfListAdminActivity

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.database.ValueEventListener
import com.rahmanadiyanto.mathlearn.databinding.ActivityPdfListAdminBinding
import java.lang.Exception

class PdfListAdminActivity : AppCompatActivity() 

    //view binding
    private lateinit var binding: ActivityPdfListAdminBinding

    private companion object
        const val TAG = "PDF_LIST_ADMIN_TAG"
    

    //category Id, Title
    private var categoryId = ""
    private var category =""

    //array list to hold books
    private lateinit var pdfArrayList: ArrayList<ModelPdf>

    //adapter
    private lateinit var adapterPdfAdmin: AdapterPdfAdmin

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        binding = ActivityPdfListAdminBinding.inflate(layoutInflater)
        setContentView(binding.root)

        //get from intent, that we passed from adapter
        val intent = intent
        categoryId = intent.getStringExtra("categoryId")!!
        category = intent.getStringExtra("category")!!

       //handle click, back
        binding.backBtn.setOnClickListener 
            onBackPressed()
        

        //set pdf category
        binding.subTitleTv.text = category

        //load pdf/books
        loadPdfList()

        //search
        binding.searchEt.addTextChangedListener(object : TextWatcher
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) 

            

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) 
                try 
                    adapterPdfAdmin.filter.filter(s)
                
                catch (e : Exception)
                    Log.d(TAG, "onTextChanged: $e.message")

                

            

            override fun afterTextChanged(s: Editable?) 

            
        )

    

    private fun loadPdfList() 
        //init array list
        pdfArrayList = ArrayList()

        //setup adapter
        adapterPdfAdmin = AdapterPdfAdmin(this@PdfListAdminActivity,pdfArrayList)
        binding.booksRv.adapter = adapterPdfAdmin

        val ref = FirebaseDatabase.getInstance().getReference("Books")
        ref.orderByChild("categoryId").equalTo(categoryId)
            .addValueEventListener(object : ValueEventListener
                override fun onDataChange(snapshot: DataSnapshot) 
                   //clear list before adding data into it
                    pdfArrayList.clear()
                    for (ds in snapshot.children)
                        //get data
                        val model = ds.getValue(ModelPdf::class.java)

                        //adding to list
                        if (model != null) 
                            pdfArrayList.add(model)
                            Log.d(TAG, "onDataChange: $model.title $model.categoryId")
                        
                    

                    binding.booksRv.adapter = adapterPdfAdmin

                

                override fun onCancelled(error: DatabaseError) 

                
            )

    

FilterPdfAdmin

import android.widget.Filter

/*-----Use to filter data from recyclerview | search pdf from pdf list in recyclerview----*/
class FilterPdfAdmin : Filter 

    //arraylist in which we want to search
    private var filterList : ArrayList<ModelPdf> = ArrayList()

    //adapter in which filter need to be implemented
    private var adapterPdfAdmin : AdapterPdfAdmin

    //constructor
    constructor(filterList: ArrayList<ModelPdf>, adapterPdfAdmin: AdapterPdfAdmin) 
        this.filterList = filterList
        this.adapterPdfAdmin = adapterPdfAdmin
    

    override fun performFiltering(constraint: CharSequence?): FilterResults 
        var constraint2 = constraint //value to search
        val results = FilterResults()

        //value to be search should not be null and not empty
        if (constraint2 != null && constraint2.isNotEmpty())

            //change to uppercase, or lowercase to avoid sensitivity
            constraint2 =constraint2.toString().lowercase()
            var filteredModels = ArrayList<ModelPdf>()
            for (i in filterList.indices)
                //validate if match
                if (filterList[i].title.lowercase().contains(constraint2))
                    //search value is similar to value in list, add to filtered list
                    filteredModels.add(filterList[i])
                
            
            results.count = filteredModels.size
            results.values = filteredModels
        
        else
            //value is either null or empty, return all data
            results.count = filterList.size
            results.values = filterList
        
        return results // don't miss
    

    override fun publishResults(constraint: CharSequence, results: FilterResults) 
        //apply filter changes
        adapterPdfAdmin.pdfArrayList = results.values as ArrayList<ModelPdf>

        //notify changes
        adapterPdfAdmin.notifyDataSetChanged()

    

AdapterPdfAdmin

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Filter
import android.widget.Filterable
import androidx.recyclerview.widget.RecyclerView
import com.rahmanadiyanto.mathlearn.databinding.RowPdfAdminBinding

class AdapterPdfAdmin : RecyclerView.Adapter<AdapterPdfAdmin.HolderPdfAdmin>, Filterable

    //context
    private val context: Context

    //arraylist to hold pdfs
    public var pdfArrayList: ArrayList<ModelPdf>
    private val filterList: ArrayList<ModelPdf>

    //view binding
    private lateinit var binding: RowPdfAdminBinding

    //filter object
    private var filter : FilterPdfAdmin? = null

    //constructor
    constructor(context: Context, pdfArrayList: ArrayList<ModelPdf>) : super() 
        this.context = context
        this.pdfArrayList = pdfArrayList
        this.filterList = pdfArrayList
    



    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HolderPdfAdmin 
        //bind/inflate layout row_pdf_admin.xml
        binding = RowPdfAdminBinding.inflate(LayoutInflater.from(context), parent, false)

        return HolderPdfAdmin(binding.root)
    

    override fun onBindViewHolder(holder: HolderPdfAdmin, position: Int) 
        /*------ get data, set data, handle click etc----------*/

        //get data
        val model = pdfArrayList[position]
        val pdfId = model.id
        val categoryId = model.categoryId
        val title = model.title
        val description = model.description
        val pdfUrl = model.url
        val timestamp = model.timestamp

        // convert timestamp to dd/mm/yyyy format
        val formattedDate = MyApplication.formatTimeStamp(timestamp)

        //set data
        holder.titleTv.text = title
        holder.descriptionTv.text = description
        holder.dateTv.text = formattedDate

        //load further detail like category, pdf from url, pdf size

        //load category
        MyApplication.loadCategory(categoryId,holder.categoryTv)

        //we don't need page number here, pas null for page number // load pdf thumbnail
        MyApplication.loadPdfFromUrlSinglePage(pdfUrl,title,holder.pdfView,holder.progressBar,null)

        //load pdf size
        MyApplication.loadPdfSize(pdfUrl,title,holder.sizeTv)


    

    override fun getItemCount(): Int 
        return pdfArrayList.size // item count
    

    override fun getFilter(): Filter 
        if (filter == null)
            filter = FilterPdfAdmin(filterList, this)
        

        return filter as FilterPdfAdmin
    

    //view holder class for row_pdf_admin.xml
    inner class HolderPdfAdmin(itemView: View) : RecyclerView.ViewHolder(itemView)
        //UI views of row_pdf_admin.xml
        val pdfView = binding.pdfView
        val progressBar = binding.progressBar
        val titleTv = binding.titleTv
        val descriptionTv = binding.descriptionTv
        val categoryTv = binding.categoryTv
        val sizeTv = binding.sizeTv
        val dateTv = binding.dateTv
        val moreBtn = binding.moreBtn

    



【问题讨论】:

【参考方案1】:

这是 AndroidPdfViewer 库中的一个内部错误 - there are lots of issues about it on its Github page。其中一些人发布了解决方法,因此如果您需要使用这个特定的库,您可能想尝试一下。

【讨论】:

以上是关于(Kotlin,viewBinding)java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“boolean java.lang.Thread.isAlive(的主要内容,如果未能解决你的问题,请参考以下文章

Android开发:关于Databinding与Viewbinding以及kotlin-android-extensions

Android开发:关于Databinding与Viewbinding以及kotlin-android-extensions

Android开发:关于Databinding与Viewbinding以及kotlin-android-extensions

Android开发:关于Databinding与Viewbinding以及kotlin-android-extensions

android ViewBinding

android ViewBinding