You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 12:12:34