4
4
5
5
package kotlinx.coroutines.android
6
6
7
+ import android.os.*
7
8
import android.support.annotation.*
8
9
import kotlinx.coroutines.*
9
10
import java.lang.reflect.*
10
11
import kotlin.coroutines.*
11
12
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
+ }
19
22
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
- */
25
23
@Keep
26
24
internal class AndroidExceptionPreHandler :
27
25
AbstractCoroutineContextElement (CoroutineExceptionHandler ), CoroutineExceptionHandler
28
26
{
29
27
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
+ }
32
44
}
33
45
}
0 commit comments