0

im following tutorial in youtube to create searchview use kotlin. What can be the possible solution? The code of activity doesn't show any error in the android studio but on running it shows an error.

im getting error at runtime test

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)

this is dependencies used

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'
}

this is 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

    }


}
Rahman
  • 11

1 Answers1

2

It's an internal bug in the AndroidPdfViewer library - there are lots of issues about it on its Github page. Some of them have people posting workarounds, so you might want to try those if you need to use this specific library.

cactustictacs
  • 17,935
  • 2
  • 14
  • 25