0

I have an app with 5 tabs, 3 are the same fragment and two are two different fragments. This problem happens in all 5 fragments since the code is the same.

When I click the tabs really fast and there's some text in my AutoCompleteTextView, the app crashes.

I've tried to check if my components (listAdapter and ArrayAdapter) are not null before asigning or initializing them.

override fun afterTextChanged(s: Editable?) {
            val db = DataBaseHandler(context)
            var listAdapter: ArrayAdapter<String>

            Handler().postDelayed({
                search = etSearch.text.toString().trim()
                if (search.length >= 3){
                    resultList.clear()
                    products = if (isNumeric(search)) db.readData_SomeProductsId(search)
                        else db.readData_SomeProductsDesc(search)
                    for (product in products!!)
                        resultList.add(product.prod_description)
                    if (resultList.size == 1){
                        product = products!![0]
                        ETClear(etSearch)
                        addProduct()
                    } else{
                        if (resultList.size > 1){
                            listAdapter = ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, resultList)
                            etSearch.setAdapter(listAdapter)
                            etSearch.showDropDown()
                        }

                    }
                }
            }, 600)

            etSearch.setOnItemClickListener{ parent,view,position,id->
                val selectedItem = parent.getItemAtPosition(position).toString()
                product = db.readData_ProductDescription(selectedItem)!!
                ETClear(etSearch)
                addProduct()
            }
        }

The error shows as follows:

06-05 18:01:49.034 26859-26859/com.example.said.puntodeventa E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.said.puntodeventa, PID: 26859
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
    at android.view.LayoutInflater.from(LayoutInflater.java:234)
    at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:178)
    at android.widget.ArrayAdapter.<init>(ArrayAdapter.java:163)
    at com.example.said.puntodeventa.SaleFragment1$onViewCreated$1$afterTextChanged$1.run(SaleFragment1.kt:109)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:158)
    at android.app.ActivityThread.main(ActivityThread.java:7231)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

Thanks in advance

Michael Krause
  • 4,689
  • 1
  • 21
  • 25
Said
  • 53
  • 1
  • 1
  • 11

1 Answers1

2

You can't assume your Fragment will always have a non-null Context.

To fix this, it's good to understand where onAttach and onDetach fit in the Fragment lifecycle.

You've got a Runnable chunk of code that you're purposely delaying execution by 600 milliseconds. That will be more than enough time for the Fragment to be detached from its parent Activity in race conditions like the "When I click the tabs really fast" scenario you've mentioned.

The NullPointerException occurs inside of the ArrayAdapter constructor when it tries to create a LayoutInflater from your passed in Context (which is null).

According to your stack trace, the line of code in your Runnable that causes this is:

listAdapter = ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, resultList)

One way to fix this would be to null-check the context as the first line in your Runnable block and early return if it is null.

Michael Krause
  • 4,689
  • 1
  • 21
  • 25
  • I added ` } else if (context != null){ listAdapter = ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, resultList) etSearch.setAdapter(listAdapter) etSearch.showDropDown() }` Thank you so much! – Said Jun 06 '19 at 02:06