我只使用一项 Activity ,很少使用碎片。我只想在启动画面上隐藏工具栏。我这样写:
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)
}
}
}
}但它返回
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
错误。完整日志: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:正在发送信号。 PID:23070 SIG:9杜你知道如何解决吗?
最佳答案
用CoroutineScope(Dispatchers.Default).launch
替换CoroutineScope(Dispatchers.Main).launch
-您在后台线程上调用navigate()
,这会导致在后台线程上调用onDestinationChanged
,这会导致您的错误。
通过使用Dispatchers.Main
调度程序,您的navigate()
调用将在主线程上进行。请注意,协程在调用delay
时已经可以不阻塞主线程,因此在此处使用Dispatchers.Main
绝对可以。