CrashHandler.java
2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package com.studymachine.www.other;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import androidx.annotation.NonNull;
import com.studymachine.www.ui.activity.CrashActivity;
import com.studymachine.www.ui.activity.RestartActivity;
/**
* desc : Crash 处理类
*/
public final class CrashHandler implements Thread.UncaughtExceptionHandler {
/** Crash 文件名 */
private static final String CRASH_FILE_NAME = "crash_file";
/** Crash 时间记录 */
private static final String KEY_CRASH_TIME = "key_crash_time";
/**
* 注册 Crash 监听
*/
public static void register(Application application) {
Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(application));
}
private final Application mApplication;
private final Thread.UncaughtExceptionHandler mNextHandler;
private CrashHandler(Application application) {
mApplication = application;
mNextHandler = Thread.getDefaultUncaughtExceptionHandler();
if (getClass().getName().equals(mNextHandler.getClass().getName())) {
// 请不要重复注册 Crash 监听
throw new IllegalStateException("are you ok?");
}
}
@SuppressLint("ApplySharedPref")
@Override
public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) {
SharedPreferences sharedPreferences = mApplication.getSharedPreferences(CRASH_FILE_NAME, Context.MODE_PRIVATE);
long currentCrashTime = System.currentTimeMillis();
long lastCrashTime = sharedPreferences.getLong(KEY_CRASH_TIME, 0);
// 记录当前崩溃的时间,以便下次崩溃时进行比对
sharedPreferences.edit().putLong(KEY_CRASH_TIME, currentCrashTime).commit();
// 致命异常标记:如果上次崩溃的时间距离当前崩溃小于 5 分钟,那么判定为致命异常
boolean deadlyCrash = currentCrashTime - lastCrashTime < 1000 * 60 * 5;
if (AppConfig.isDebug()) {
CrashActivity.start(mApplication, throwable);
} else {
if (!deadlyCrash) {
// 如果不是致命的异常就自动重启应用
RestartActivity.start(mApplication);
}
}
// 不去触发系统的崩溃处理(com.android.internal.os.RuntimeInit$KillApplicationHandler)
if (mNextHandler != null && !mNextHandler.getClass().getName().startsWith("com.android.internal.os")) {
mNextHandler.uncaughtException(thread, throwable);
}
// 杀死进程(这个事应该是系统干的,但是它会多弹出一个崩溃对话框,所以需要我们自己手动杀死进程)
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(10);
}
}