Android Java中如何全局捕获应用崩溃日志?
Android全局捕获应用崩溃方案
为什么Activity中加try-catch没用?
你之前的操作没效果很正常:
- Fragment的生命周期方法(比如
onCreateView、onResume)由系统框架调用,不在Activity的代码执行流程里,Activity的try-catch覆盖不到这些异常。 - 子线程的未捕获异常不会自动传递到主线程,Activity的try-catch自然也抓不到。
全局捕获崩溃的可行方案
1. 自定义UncaughtExceptionHandler(覆盖绝大多数Java层崩溃)
这是最常用的全局捕获方式,能抓到主线程、子线程里所有未被try-catch包裹的异常,包括Activity、Fragment的崩溃。
步骤如下:
- 自定义异常处理器类:
public class GlobalCrashHandler implements Thread.UncaughtExceptionHandler { private Thread.UncaughtExceptionHandler defaultHandler; public GlobalCrashHandler() { // 保存系统默认的异常处理器 defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); } @Override public void uncaughtException(Thread t, Throwable e) { // 这里处理崩溃逻辑:比如记录崩溃日志、上传到服务器 Log.e("GlobalCrash", "线程:" + t.getName() + " 崩溃原因:", e); // 处理完后可以选择让系统继续处理(弹出崩溃提示),或者自己退出应用 if (defaultHandler != null) { defaultHandler.uncaughtException(t, e); } else { // 手动退出应用 android.os.Process.killProcess(android.os.Process.myPid()); System.exit(1); } } }
- 在自定义
Application的onCreate方法中设置全局处理器:
public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); // 设置全局异常处理器 Thread.setDefaultUncaughtExceptionHandler(new GlobalCrashHandler()); } }
- 别忘了在
AndroidManifest.xml中注册你的Application:
<application android:name=".MyApp" ...> ... </application>
2. 利用Android 14(API 34)的ApplicationExitInfo(事后分析崩溃)
如果你的应用适配到API 34及以上,可以用这个API获取应用上次崩溃的详细信息,适合在应用重启后分析崩溃原因:
public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); List<ApplicationExitInfo> exitInfos = am.getHistoricalProcessExitReasons(null, 0, 1); if (!exitInfos.isEmpty()) { ApplicationExitInfo exitInfo = exitInfos.get(0); // 检查是否是崩溃导致的退出 if (exitInfo.getReason() == ApplicationExitInfo.REASON_CRASH) { Log.e("CrashInfo", "上次崩溃原因:", exitInfo.getThrowable()); } } } } }
注意事项
- 不要在
uncaughtException方法中执行耗时操作,因为这个方法在崩溃线程执行,可能影响系统后续的崩溃处理流程。 - Java层面的处理器抓不到Native层(C/C++代码)的崩溃,这类情况需要用NDK的
signal机制额外处理。 - 测试时可以故意抛出异常验证效果,比如在Fragment的
onCreateView里写throw new RuntimeException("测试崩溃");,看是否能被全局处理器捕获。
内容的提问来源于stack exchange,提问作者Shawn
相关产品推荐
相关产品推荐

