我正在跟踪this official guide on coroutine,并且StrickMode一直抱怨磁盘读/写是在MainThread上完成的(即使isSignedIn使用SharedPreference),即使我已将其指定为在Dispatchers.IO上运行。

override fun onStart() {
    super.onStart()
    launch {
        val isSignedIn = async(Dispatchers.IO) { viewModel.isSignedIn() }
        val navigationAction = if (isSignedIn.await()) R.id.action_splashFragment_to_mainFragment
        else R.id.action_splashFragment_to_whatIsLoftFragment
        withContext(Dispatchers.Main) { navigateToNextWithDelay(action = navigationAction) }
    }
}
  • 我做错了什么,导致viewModel.isSignedIn()无法在后台线程上运行吗?
  • 如果代码没有错误,是否表示“因为协程实际上并未阻塞线程,所以StrictMode.detectNetwork和Disk无关”?

  • 更新:添加StrictMode配置并记录

    private fun setupStrictMode() {
        if (BuildConfig.DEBUG) {
            StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
                    .detectAll()
                    .penaltyLog()
                    .penaltyDeath()
                    .build()
            )
            StrictMode.setVmPolicy(StrictMode.VmPolicy.Builder()
                    .detectAll()
                    .penaltyLog()
                    .penaltyDeath()
                    .build()
            )
        }
    }
    

    日志:
    2018-10-14 13:11:36.411 13542-13542/io.github.louistsaitszho.loft E/AndroidRuntime: FATAL EXCEPTION: main
        Process: io.github.louistsaitszho.loft, PID: 13542
        java.lang.RuntimeException: StrictMode ThreadPolicy violation
            at android.os.StrictMode$AndroidBlockGuardPolicy.onThreadPolicyViolation(StrictMode.java:1705)
            at android.os.StrictMode$AndroidBlockGuardPolicy.lambda$handleViolationWithTimingAttempt$0(StrictMode.java:1619)
            at android.os.-$$Lambda$StrictMode$AndroidBlockGuardPolicy$9nBulCQKaMajrWr41SB7f7YRT1I.run(Unknown Source:6)
            at android.os.Handler.handleCallback(Handler.java:873)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:193)
            at android.app.ActivityThread.main(ActivityThread.java:6669)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
         Caused by: android.os.strictmode.DiskReadViolation
            at android.os.StrictMode$AndroidBlockGuardPolicy.onReadFromDisk(StrictMode.java:1504)
            at java.io.UnixFileSystem.getBooleanAttributes(UnixFileSystem.java:241)
            at java.io.File.isDirectory(File.java:845)
            at dalvik.system.DexPathList$Element.maybeInit(DexPathList.java:696)
            at dalvik.system.DexPathList$Element.findResource(DexPathList.java:729)
            at dalvik.system.DexPathList.findResources(DexPathList.java:526)
            at dalvik.system.BaseDexClassLoader.findResources(BaseDexClassLoader.java:174)
            at java.lang.ClassLoader.getResources(ClassLoader.java:839)
            at java.util.ServiceLoader$LazyIterator.hasNextService(ServiceLoader.java:349)
            at java.util.ServiceLoader$LazyIterator.hasNext(ServiceLoader.java:402)
            at java.util.ServiceLoader$1.hasNext(ServiceLoader.java:488)
            at kotlin.collections.CollectionsKt___CollectionsKt.toCollection(_Collections.kt:1062)
            at kotlin.collections.CollectionsKt___CollectionsKt.toMutableList(_Collections.kt:1095)
            at kotlin.collections.CollectionsKt___CollectionsKt.toList(_Collections.kt:1086)
            at kotlinx.coroutines.experimental.MainDispatcherLoader.<clinit>(Dispatchers.kt:97)
            at kotlinx.coroutines.experimental.Dispatchers.getMain(Dispatchers.kt:54)
            at io.github.louistsaitszho.loft.ScopedFragment.getCoroutineContext(ScopedFragment.kt:20)
            at kotlinx.coroutines.experimental.CoroutineContextKt.newCoroutineContext(CoroutineContext.kt:81)
            at kotlinx.coroutines.experimental.BuildersKt__Builders_commonKt.launch(Builders.common.kt:49)
            at kotlinx.coroutines.experimental.BuildersKt.launch(Unknown Source:1)
            at kotlinx.coroutines.experimental.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:46)
            at kotlinx.coroutines.experimental.BuildersKt.launch$default(Unknown Source:1)
            at io.github.louistsaitszho.loft.splash.SplashFragment.onStart(SplashFragment.kt:28)
            at android.support.v4.app.Fragment.performStart(Fragment.java:2372)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1467)
            at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)
            at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3244)
            at android.support.v4.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:3206)
            at android.support.v4.app.Fragment.performStart(Fragment.java:2378)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1467)
            at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)
            at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)
            at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3244)
            at android.support.v4.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:3206)
            at android.support.v4.app.FragmentController.dispatchStart(FragmentController.java:206)
            at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:605)
    2018-10-14 13:11:36.412 13542-13542/io.github.louistsaitszho.loft E/AndroidRuntime:     at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:177)
            at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1391)
            at android.app.Activity.performStart(Activity.java:7157)
            at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2937)
            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:1808)
            at android.os.Handler.dispatchMessage(Handler.java:106)
    

    最佳答案

    我认为您遇到了Slow android Dispatchers.Main init中报告的问题。

    这在堆栈跟踪的以下部分中可见:

        at dalvik.system.BaseDexClassLoader.findResources(BaseDexClassLoader.java:174)
        at java.lang.ClassLoader.getResources(ClassLoader.java:839)
        at java.util.ServiceLoader$LazyIterator.hasNextService(ServiceLoader.java:349)
        at java.util.ServiceLoader$LazyIterator.hasNext(ServiceLoader.java:402)
        at java.util.ServiceLoader$1.hasNext(ServiceLoader.java:488)
    

    它已在1.3.3 which landed in December版本中修复:

    10-08 12:07