集成Firebase Crashlytics 2.9.1后自定义UncaughtExceptionHandler致崩溃无日志
解决自定义UncaughtExceptionHandler导致Firebase Crashlytics无法记录崩溃的问题
这个问题我之前帮不少开发者排查过,核心原因很明确:你调用Thread.setDefaultUncaughtExceptionHandler()时直接覆盖了Firebase Crashlytics预先注册的异常处理器——Crashlytics正是靠这个默认处理器捕获、处理并上报崩溃信息的,被覆盖后自然就收不到数据了。
解决方案:保留Crashlytics的异常处理逻辑,再执行自定义行为
我们需要先保存原本的默认异常处理器(也就是Crashlytics的),在自定义处理器中先让它完成崩溃上报,再执行跳转启动页的逻辑。修改后的代码如下:
public class BaseActivity extends FragmentActivity { // 保存Crashlytics注册的默认异常处理器 private Thread.UncaughtExceptionHandler defaultExceptionHandler; @Override protected void onCreate(Bundle arg0) { super.onCreate(arg0); // 先获取并保存默认的异常处理器 defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); // 再设置自定义的异常处理器 Thread.setDefaultUncaughtExceptionHandler(handleAppCrash); } /** * 自定义崩溃处理器:先让Crashlytics上报,再执行跳转逻辑 */ private Thread.UncaughtExceptionHandler handleAppCrash = new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread thread, Throwable ex) { // 第一步:让Crashlytics处理崩溃信息(必须放在自定义逻辑前面) if (defaultExceptionHandler != null) { defaultExceptionHandler.uncaughtException(thread, ex); } // 第二步:执行你的自定义跳转逻辑 Intent intent = new Intent(BaseActivity.this, MainActivity.class); // 添加必要的Flag,确保启动页能正常打开 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); // 注意:不要立刻调用System.exit(0),给Crashlytics留足异步上报的时间 // 延迟2秒再退出,足够完成绝大多数场景下的上报 new Handler(Looper.getMainLooper()).postDelayed(() -> { System.exit(0); }, 2000); } }; }
关键细节说明
- 保存默认处理器:这一步是核心,确保Crashlytics的崩溃捕获逻辑不会被完全替换。
- 先执行默认处理器逻辑:必须把
defaultExceptionHandler.uncaughtException()放在自定义逻辑前面,让Crashlytics优先处理崩溃信息。 - 延迟退出应用:Crashlytics的崩溃上报是异步操作,如果立刻调用
System.exit(0)会终止进程,导致上报失败。2秒的延迟足够完成绝大多数场景下的上报。 - 添加
FLAG_ACTIVITY_NEW_TASK:在异常处理器的上下文里启动Activity,必须添加这个Flag,否则会抛出ActivityNotFoundException或者无法正常启动Activity。
测试验证
你可以在某个页面主动抛出一个异常来测试:
// 在某个Activity的点击事件里添加 throw new RuntimeException("测试Crashlytics上报");
崩溃后等待几秒,再去Firebase Crashlytics控制台查看,应该就能看到这条崩溃记录了。
内容的提问来源于stack exchange,提问作者Durgesh Patel
相关产品推荐
相关产品推荐

