(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