kotlin 异步异常处理

Ler*_*tai 5 crash android asynchronous coroutine kotlin

鉴于以下代码段,我不明白为什么我的 android 应用程序崩溃。我在独立的 kotlin 应用程序中进行了测试,但这不会发生。

class LoginActivity : AppCompatActivity(), CoroutineScope
{
     lateinit var job: Job
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job


   override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)
        job = Job()

        try
        {
            launch()
            {
                try
                {
                    var res = async { test() }

                    res.await()

                } 
                catch (e2: java.lang.Exception)
                {

                }
            }

        }
        catch (e: java.lang.Exception)
        {


        }
    }

    fun test(): String
    {
        throw java.lang.Exception("test ex")
        return "";
    }
}


 --------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: ro.ingr.ingeeasafety, PID: 11298
    java.lang.Exception: test ex
        at ro.ingr.ingeeasafety.activities.LoginActivity.test(LoginActivity.kt:72)
        at ro.ingr.ingeeasafety.activities.LoginActivity$onCreate$1$res$1.invokeSuspend(LoginActivity.kt:48)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)
        at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:236)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6119)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Run Code Online (Sandbox Code Playgroud)

独立的 kotlin 应用代码,执行到“主端” println

class app
{
    companion object :CoroutineScope
    {
        lateinit var job: Job
        override val coroutineContext: CoroutineContext
            get() = Dispatchers.Default+ job

        init
        {
            job=Job()
        }

        @JvmStatic
        fun main(args: Array<String>)
        {
            launch()
            {
                try
                {
                    async()
                    {
                        println("async start")
                        throw Exception("aaa")

                    }.await()
                }
                catch (e: Exception)
                {
                    println("async exception")
                }
            }


            println("main end")

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试创建一个流,我从某个地方加载一些东西,如果加载操作失败,我的应用程序不会崩溃。我期待异常在定义的处理程序中被捕获。

LE:我添加了崩溃堆栈跟踪。

ngl*_*ber 18

你可以在这里找到你的答案:https : //proandroiddev.com/kotlin-coroutines-patterns-anti-patterns-f9d12984c68e

总而言之,有几种方法可以使用async.

1 - 包裹async通话supervisorScope

launch {
    supervisorScope {
        val task = async {
            methodThatThrowsException()
        }
        try {
            updateUI("Ok ${task.await()}")
        } catch (e: Throwable) {
            showError("Erro! ${e.message}")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

2 - 传递 aSupervisorJob作为参数

launch { 
    // parentJob (optional) is the parent Job of the CoroutineContext
    val task = async(SupervisorJob(parentJob)) {
        methodThatThrowsException()
    }
    try {
        updateUI("Ok ${task.await()}")
    } catch (e: Throwable) {
        showError("Erro! ${e.message}")
    }
}
Run Code Online (Sandbox Code Playgroud)

3 -包装asynccoroutineScope

launch {
    try {
        coroutineScope {
            val task = async {
                methodThatThrowsException()
            }
            updateUI("Ok ${task.await()}")
        }
    } catch (e: Throwable) {
        showError("Erro! ${e.message}")
    }
}
Run Code Online (Sandbox Code Playgroud)