Issue
I use one activity and few fragments. I want to hide toolbar only on splash screen. I wrote this:
class MainActivity : AppCompatActivity() {
lateinit var auth: FirebaseAuth
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
auth = Firebase.auth
val currentUser = auth.currentUser
updateUI(currentUser)
setSupportActionBar(toolbar)
findNavController(R.id.nav_container).addOnDestinationChangedListener { _, destination, _ ->
when (destination.id) {
R.id.splashScreenFragment -> {
supportActionBar?.hide()
appBarLayoutz.visibility = View.GONE
}
else -> {
supportActionBar?.show()
appBarLayoutz.visibility = View.VISIBLE
}
}
}
}
private fun updateUI(currentUser: FirebaseUser?) {
if (currentUser != null) {
findNavController(R.id.nav_container).navigate(R.id.action_splashScreenFragment_to_mainPageFragment)
} else {
CoroutineScope(Dispatchers.Default).launch {
delay(500)
findNavController(R.id.nav_container).navigate(R.id.action_splashScreenFragment_to_loginFragment)
}
}
}
}
but it returns android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
error. Full logs:
2020-10-04 18:36:56.949 23070-23235/pl.rybson.musicquiz E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
Process: pl.rybson.musicquiz, PID: 23070
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:8613)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1528)
at android.view.View.requestLayout(View.java:24634)
at android.view.View.setFlags(View.java:15312)
at android.view.View.setVisibility(View.java:10919)
at com.google.android.material.appbar.AppBarLayout.setVisibility(AppBarLayout.java:417)
at pl.rybson.musicquiz.ui.MainActivity$onCreate$1.onDestinationChanged(MainActivity.kt:43)
at androidx.navigation.NavController.dispatchOnDestinationChanged(NavController.java:498)
at androidx.navigation.NavController.navigate(NavController.java:1097)
at androidx.navigation.NavController.navigate(NavController.java:935)
at androidx.navigation.NavController.navigate(NavController.java:868)
at androidx.navigation.NavController.navigate(NavController.java:854)
at androidx.navigation.NavController.navigate(NavController.java:842)
at pl.rybson.musicquiz.ui.MainActivity$updateUI$1.invokeSuspend(MainActivity.kt:57)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
2020-10-04 18:36:56.959 23070-23235/pl.rybson.musicquiz I/Process: Sending signal. PID: 23070 SIG: 9
Du you have idea how to fix it?
Solution
Replace CoroutineScope(Dispatchers.Default).launch
with CoroutineScope(Dispatchers.Main).launch
- you're calling navigate()
on a background thread, which causes your onDestinationChanged
to be called on a background thread, which causes your error.
By using the Dispatchers.Main
dispatcher, your navigate()
call will happen on the main thread. Note that coroutines already handle not blocking the main thread when you call delay
, so it absolutely fine to use Dispatchers.Main
there.
Answered By - ianhanniballake
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.