Closed9

Android の GlobalExceptionHandler を考える

tkttkt

それっぽい知見が全然見つからないのはなぜなのか

tkttkt

2015年あたりで話されてるのはちょこちょこあるけど最近話されてるのはあまりなさそうだった
日本語で話されているものは限りなく少ない
わりとみんなぶつかりそうな話なのにどうしてなのか
UncaughtExceptionHandler を触ること自体が暗黙のアンチパターン説

tkttkt

あとは、Crashlitics とかのライブラリに投げるから、多くの場合は気にしなくても良い、か、

tkttkt

https://github.com/firebase/firebase-android-sdk/blob/ae357812a87c4ae48596d041ffb68055ecdf7b0f/firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/CrashlyticsController.java#L140-L159
Ceashlitics での実装
下手にこのあたりの実装を真似ると、Crashlitics を入れていたときに競合したりしそうで怖い

https://github.com/firebase/firebase-android-sdk/issues/2005
ExceptionHandle を抜き出して話していてわかりやすそう

tkttkt

やりたいこと

  • デフォルトのクラッシュダイアログを置き換える
  • クラッシュ時にログ送信等の特定の動作を行う
tkttkt
  • クラッシュダイアログの代わりにアクティビティ呼び出し
  • クラッシュ時にログ送信

できた

tkttkt
E/CustomCrashHandler: uncaughtException: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802) 
     Caused by: とりたいException

とりたいException の位置にある Exception に応じて処理を切り分けたいんだけれど、これはどうやって取れば良いのか
exception を直接比較すると RuntimeException として評価されて切り分けができない

tkttkt

こうした

private fun getApplicationCause(throwable: Throwable?): Throwable? {
    if (throwable == null) {
        return null
    }
    return when (throwable) {
        is RuntimeException -> getApplicationCause(throwable.cause)
        is InvocationTargetException -> getApplicationCause(throwable.cause)
        else -> throwable
    }
}
このスクラップは2021/05/28にクローズされました