If when the app switch to landscape mode the method onCreate() is recalled, why do I receive this error: kotlin.UninitializedPropertyAccessException: lateinit property has not been initialized
only if the app enters in landscape mode but not in the portrait mode?
It sounds me that I need to clean some resources in onPause() or onStop() first to recall the onCreate()
My main 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
}
}
The full error:
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.access$2100(SearchView.java:99)
at android.widget.SearchView$10.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
is the line: adapter.getFilter(binding.spnFilter.selectedItem.toString(), this).filter(p0)
The adaper is initialized only after the data is loaded (asynchronously) but setUIControl()
is called before (while the data is still being loaded).
setUIControl()
sets a TextChangeListener
which accesses the adapter variable when onQueryTextChange
is called.
When the search field is populated and the screen is rotated, Android restores the search field (onRestoreInstanceState
) and thus triggers onQueryTextChange
.
The solution is easy, just call setUIControl()
after the RecyclerView is fully initialized (after the binding.rvComuni.adapter
).