コルーチンで例外処理がどのように機能するのか非常に混乱します。コトリンコルーチンが嚥下する例外
私は、同期コードのように例外を渡すサスペンド機能の連鎖を持つことができると考えていました。だからRetrofitがIOExceptionを投げたとすると、プレゼンターなどのサスペンド機能のチェーンの始めにその例外を処理して、ユーザーにエラーを表示することができました。
私はコルーチンを試すためにこの簡単な例を作ったが、例外の実行に失敗した後にthrow Exception
のコードを呼び出すと例外が発生するが、例外はアプリケーションをクラッシュさせない。
package com.example.myapplication
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Button
import android.widget.TextView
import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.launch
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val text = findViewById<TextView>(R.id.thing_text)
val button = findViewById<Button>(R.id.thing_button)
var count = 0
button.setOnClickListener {
launch {
count++
// throw Exception("Boom")
val string = delayedStringOfInt(count)
runOnUiThread { text.text = string }
}
}
}
suspend fun delayedStringOfInt(int: Int): String {
delay(1000)
// throw Exception("Boom")
return int.toString()
}
}
私はasync
とCoroutineExceptionHandler
を使用して試してみました。
私は前に 'await'と' async'をしようとしたが、それは '関数をサスペンドだけコルーチンや他から呼び出されるべきで待つことに文句を中断することなく、runBlocking'が働く'でそれをすべてを包む、ただしfunction.'を中断しますコードの非同期実行'runBlocking'は、内部のコルーチンが完了するまでブロックすることを期待していたので、混乱する名前です。私の場合、あなたが急にボタンをクリックした場合、急速ではなく毎秒増加する数字が得られると予想していました。私はこれを答えとしてマークしますが、固定コードを別の答えに入れます。 – TTransmit
もっと見ると、 'runBlocking'がUIスレッドをブロックしているのがわかります。これは私が望むものではありません。私はコールバックを使用してみる必要があります。 – TTransmit
ここでkotlinx 'Continuation'を使うと、今まで私に醜いコールバック地獄を与えているだけです。 – TTransmit