为什么进入横向模式时应用程序崩溃? kotlin.UninitializedPropertyAccessException: lateinit 属性 尚未初始化

Why app crash when enter in landscape mode? kotlin.UninitializedPropertyAccessException: lateinit property has not been initialized

如果应用切换到横向模式时调用了onCreate()方法,为什么会出现这个错误:kotlin.UninitializedPropertyAccessException: lateinit property has not been initialized只有当应用进入横向模式而不是纵向模式时?

听起来我需要先清理 onPause() 或 onStop() 中的一些资源才能调用 onCreate()

我的主要activity:

class MainActivity : AppCompatActivity() {

companion object {
    const val FILENAME = "file.txt"
    const val TAG = "APP"
}

private lateinit var binding: ActivityMainBinding
private lateinit var adapter: AdapterComuni

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    loadData()
    setUIControl()
}

private fun loadData() {
    val reader = assets.open(FILENAME).bufferedReader()
    CoroutineScope(Dispatchers.IO).launch {
        val listaComuni = ListaComuni()
        reader.useLines { lines ->
            lines.forEach {
                listaComuni.add(Comune(it))
            }
            launch(Dispatchers.Default) {
                listaComuni.listaComuni.sortBy { it.comune }
                launch(Dispatchers.Main) {
                    Log.d(TAG, "LETTO!")
                    adapter = AdapterComuni(
                        listaComuni
                    )
                    val layoutManager = LinearLayoutManager(this@MainActivity)
                    binding.rvComuni.layoutManager = layoutManager
                    binding.rvComuni.adapter = adapter
                }
            }
        }
    }
}

private fun setUIControl() {
    binding.svComuni.setOnQueryTextListener(TextChangeListener())
}

inner class TextChangeListener: SearchView.OnQueryTextListener {
    override fun onQueryTextSubmit(p0: String?): Boolean {
        return findAllSimilarCountry(p0)
    }

    override fun onQueryTextChange(p0: String?): Boolean {
        return findAllSimilarCountry(p0)
    }

}

private fun findAllSimilarCountry(p0: String?): Boolean {
    adapter.getFilter(binding.spnFilter.selectedItem.toString(), this).filter(p0)
    return true
}

}

完整错误:

kotlin.UninitializedPropertyAccessException: lateinit property adapter has not been initialized
    at com.user.app.MainActivity.findAllSimilarCountry(MainActivity.kt:73)
    at com.user.app.MainActivity.access$findAllSimilarCountry(MainActivity.kt:14)
    at com.user.app.MainActivity$TextChangeListener.onQueryTextChange(MainActivity.kt:67)
    at android.widget.SearchView.onTextChanged(SearchView.java:1261)
    at android.widget.SearchView.access00(SearchView.java:99)
    at android.widget.SearchView.onTextChanged(SearchView.java:1789)
    at android.widget.TextView.sendOnTextChanged(TextView.java:10069)
    at android.widget.TextView.setText(TextView.java:5938)
    at android.widget.TextView.setText(TextView.java:5776)
    at android.widget.EditText.setText(EditText.java:122)
    at android.widget.TextView.setText(TextView.java:5733)
    at android.widget.TextView.onRestoreInstanceState(TextView.java:5601)
    at android.view.View.dispatchRestoreInstanceState(View.java:18820)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3883)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3883)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3883)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3883)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3883)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3883)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3883)
    at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3883)
    at android.view.View.restoreHierarchyState(View.java:18798)
    at com.android.internal.policy.PhoneWindow.restoreHierarchyState(PhoneWindow.java:2234)
    at android.app.Activity.onRestoreInstanceState(Activity.java:1210)
    at android.app.Activity.performRestoreInstanceState(Activity.java:1164)
    at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1338)
    at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3470)
    at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:180)
    at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:165)
    at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:142)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
    at android.os.Handler.dispatchMessage(Handler.java:112)
    at android.os.Looper.loop(Looper.java:216)
    at android.app.ActivityThread.main(ActivityThread.java:7625)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

MainActivity.kt:73 是行:adapter.getFilter(binding.spnFilter.selectedItem.toString(), this).filter(p0)

adaper 仅在数据加载后(异步)初始化,但 setUIControl() 在此之前调用(数据仍在加载时)。

setUIControl() 设置一个 TextChangeListener,它在调用 onQueryTextChange 时访问适配器变量。 当填充搜索字段并旋转屏幕时,Android 恢复搜索字段 (onRestoreInstanceState),从而触发 onQueryTextChange.

解决方法很简单,在RecyclerView完全初始化后(binding.rvComuni.adapter之后)调用setUIControl()即可。