如何避免具有延迟的Runnable的片段中出现NullPointerException

时间:2019-06-05 23:19:41

标签: android kotlin

我有一个带有5个标签的应用,其中3个是相同的片段,两个是两个不同的片段。由于代码相同,所以在所有5个片段中都会发生此问题。

当我非常快地单击选项卡并且我的AutoCompleteTextView中有一些文本时,应用程序崩溃了。

在分配或初始化组件之前,我试图检查我的组件(listAdapterArrayAdapter)是否不为空。

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()
            }
        }

错误显示如下:

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)

预先感谢

1 个答案:

答案 0 :(得分:2)

您不能假设您的Fragment始终具有非null上下文。

要解决此问题,最好了解onAttachonDetachFragment lifecycle中的位置。

您有一个可运行的代码块,有意将执行延迟600毫秒。像您提到的"When I click the tabs really fast"场景那样,这将是足够多的时间使Fragment从其父Activity中分离出来。

当NullPointerException试图根据传入的Context创建一个LayoutInflater时,它发生在ArrayAdapter constructor内部(为null)。

根据您的堆栈跟踪,Runnable中导致此问题的代码行是:

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

解决此问题的一种方法是将上下文作为您Runnable块的第一行进行空检查,如果为空,则尽早返回。