我只使用一项 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绝对可以。

07-27 14:53