44
55package kotlinx.coroutines.android
66
7+ import android.os.*
78import android.support.annotation.*
89import kotlinx.coroutines.*
910import java.lang.reflect.*
1011import kotlin.coroutines.*
1112
12- private val getter =
13- try {
14- Thread ::class .java.getDeclaredMethod(" getUncaughtExceptionPreHandler" ).takeIf {
15- Modifier .isPublic(it.modifiers) && Modifier .isStatic(it.modifiers)
16- }
17- }
18- catch (e: Throwable ) { null /* not found */ }
13+ private val getter by lazy {
14+ try {
15+ Thread ::class .java.getDeclaredMethod(" getUncaughtExceptionPreHandler" ).takeIf {
16+ Modifier .isPublic(it.modifiers) && Modifier .isStatic(it.modifiers)
17+ }
18+ } catch (e: Throwable ) {
19+ null /* not found */
20+ }
21+ }
1922
20- /* *
21- * Uses Android's `Thread.getUncaughtExceptionPreHandler()` whose default behavior is to log exception.
22- * See
23- * [here](https://github.com/aosp-mirror/platform_frameworks_base/blob/2efbc7239f419c931784acf98960ed6abc38c3f2/core/java/com/android/internal/os/RuntimeInit.java#L142)
24- */
2523@Keep
2624internal class AndroidExceptionPreHandler :
2725 AbstractCoroutineContextElement (CoroutineExceptionHandler ), CoroutineExceptionHandler
2826{
2927 override fun handleException (context : CoroutineContext , exception : Throwable ) {
30- (getter?.invoke(null ) as ? Thread .UncaughtExceptionHandler )
31- ?.uncaughtException(Thread .currentThread(), exception)
28+ /*
29+ * If we are on old SDK, then use Android's `Thread.getUncaughtExceptionPreHandler()` that ensures that
30+ * an exception is logged before crashing the application.
31+ *
32+ * Since Android Pie default uncaught exception handler always ensures that exception is logged without interfering with
33+ * pre-handler, so reflection hack is no longer needed.
34+ *
35+ * See https://android-review.googlesource.com/c/platform/frameworks/base/+/654578/
36+ */
37+ val thread = Thread .currentThread()
38+ if (Build .VERSION .SDK_INT >= 28 ) {
39+ thread.uncaughtExceptionHandler.uncaughtException(thread, exception)
40+ } else {
41+ (getter?.invoke(null ) as ? Thread .UncaughtExceptionHandler )
42+ ?.uncaughtException(thread, exception)
43+ }
3244 }
3345}
0 commit comments