SwipeRefreshLayout 在协程中被清空

SwipeRefreshLayout gets nulled in a coroutine

我的布局中有一个 SwipeRefreshLayout,当调用它时 (setOnRefreshListener),我正在使用协程刷新我的 recyclerview 中的数据。

它按预期工作,但从最近几天开始,我的 Crashlytics 发生了一些崩溃,日志如下 -

Fatal Exception: java.lang.IllegalStateException: refresh must not be null
   at com.example.fragments.DataFragment$refreshData.invokeSuspend + 189(DataFragment.java:189)
   at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith + 33(BaseContinuationImpl.java:33)
   at kotlinx.coroutines.DispatchedTask.run + 233(DispatchedTask.java:233)
   at android.os.Handler.handleCallback + 751(Handler.java:751)
   at android.os.Handler.dispatchMessage + 95(Handler.java:95)
   at android.os.Looper.loop + 154(Looper.java:154)
   at android.app.ActivityThread.main + 6816(ActivityThread.java:6816)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run + 1563(ZygoteInit.java:1563)
   at com.android.internal.os.ZygoteInit.main + 1451(ZygoteInit.java:1451)

这是 refreshData() 方法 -

private fun refreshData() {
    if (actionMode != null) actionMode!!.finish()
    myAdapter = Adapter(type, this@DataFragment)
    myAdapter!!.setEmptyView(empty_view)
    recycler_view.adapter = myAdapter
    refresh.isRefreshing = true

    //Get the Data List...
    launch {
        delay(1000)
        val dataList = getTheData() //This method uses withContext(Dispatchers.IO)
        myAdapter!!.addAll(dataList)
        myAdapter!!.toogleEmptyView()
        if (refresh.isRefreshing) refresh.isRefreshing = false //This is where the crash occurs, according to Crashlytics
    }
}

我正在使用 kotlin-android-extensions 所以没有 findViewById()

这个错误与您的布局有关,我的意思是当您使用 kotlin-android-extensions 时,您必须始终确保 imort 正确 xml 在您的 kotlin 文件顶部。

勾选这个选项

1) 有时你在两个不同的布局中有相同的 id,比如刷新器,所以这可能会导致崩溃。您检查一下这个刷新器是否与您布局中的相同(您可以在刷新器上单击 cntr + B)

2) 有时您会为不同的 Api 创建两个不同的布局,例如 21 以上,所以在某些低于 21 的设备中会发生此错误。

希望对您有所帮助。如果我记得更多我写下来

我最终放弃了在我的片段中使用 synthetic 布局,因为我无法让它工作。
我也试过像 this@DataFragment.refresh 那样访问变量,我想也许变量在协程范围内,所以它不可访问(但它应该是,因为 CoroutineContextDispatchers.Main) 但这也不起作用。


最终在 onViewCreated() 方法中使用相同的旧 rootView.findViewById() 并且它不再抛出该异常。