Vik*_*kov 2 android kotlin android-memory kotlin-coroutines
我真的很高兴我将长期运行的任务切换到了协程,这些任务不断产生UI 线程的结果。与 Android 中的 AsyncTask 或常规线程相比,它提高了性能并将内存使用量减少了 3 倍,并且所有内存泄漏都消失了。
唯一的问题是,我不知道在某个时间发生异常后我应该如何重新启动长时间运行的操作......
在阅读了大量文章后,我觉得我根本不了解协程中的异常处理。让我知道如何实现所需的行为。
lateinit var initEngineJob: Job
override val coroutineContext: CoroutineContext
get() = initEngineJob + Dispatchers.Main
Run Code Online (Sandbox Code Playgroud)
fun initWorkEngineCoroutine()
{
launch {
while(true) {
val deferred = async(Dispatchers.Default) {
getResultsFromEngine()
}
val result = deferred.await()
if (result != null) {
//UI thread
draw!!.showResult(result)
}
}
}
}
fun getResultsFromEngine() :Result? {
result = // some results from native c++ engine, which throws exception at some times
return result
}
Run Code Online (Sandbox Code Playgroud)
我不知道我应该把 try catch 放在哪里。我试图用 try catch 包围 deferred.await(),但我无法在 catch 块中调用相同的方法来重试长时间运行的任务。我试过SupervisorJob (),但也没有成功。我仍然无法再次调用initWorkEngineCoroutine()并启动新的协程......
最终帮助解决这个问题:)
You should treat your code as linear imperative and try/catch where it makes the most logical sense in your code. With this mindset, your question is probably less about coroutines and more about try/catch retry. You might do something like so:
fun main() {
GlobalScope.launch {
initWorkEngineCoroutine()
}
}
suspend fun initWorkEngineCoroutine() {
var failures = 0
val maxFailures = 3
while(failures <= maxFailures) {
try {
getResultsFromEngine()?.let {
draw!!.showResult(it)
}
} catch (e: Exception) {
failures++
}
}
}
// withContext is like async{}.await() except an exception occuring inside
// withContext can be caught from inside the coroutine.
// here, we are mapping getResultFromEngine() to a call to withContext and
// passing withContext the lambda which does the work
suspend fun getResultsFromEngine() :Result? = withContext(Dispatchers.Default) {
Result()
}
Run Code Online (Sandbox Code Playgroud)
I've included some logic to prevent infinite loop. It's probably not going to fit your requirements, but you might consider some sort of thing to prevent an issue where exceptions are raised immediately by getResultsFromEngine() and end up causing an infinite loop that could result in unexpected behavior and potential stackoverflow.
| 归档时间: |
|
| 查看次数: |
3966 次 |
| 最近记录: |