直接设置全局未捕获异常处理器可接管UI线程崩溃处置权,避免闪退弹窗、保持进程存活并完成日志记录或上报;关键在于替换默认UncaughtExceptionHandler,在回调中谨慎执行安全操作,严禁新建线程或跨线程UI操作。

Android 主线程防闪退:替换默认 UncaughtExceptionHandler
Android 主线程(UI 线程)一旦抛出未捕获异常,系统会弹出“应用已停止”对话框并终止进程。你可以在 Application 的 onCreate() 中提前注册自定义处理器:
- 调用 Thread.setDefaultUncaughtExceptionHandler(...) 替换系统默认行为
- 在 uncaughtException() 回调里,不要调用 super 或原系统 handler,否则仍会闪退
- 可安全执行的操作包括:写入本地日志文件(不能用 SharedPreferences 或新线程)、同步上传 crash 信息(注意阻塞风险)、调用 Process.killProcess() + System.exit(1) 主动退出(避免残留状态)
- 若想“不退出”,需额外机制——比如启动一个兜底 Activity 显示友好提示,再引导重启;但主线程本身已无法恢复,必须另起流程
JavaFX 防 UI 线程崩溃:必须配合 Platform.runLater
JavaFX 的 UI 操作强制要求在 JavaFX 应用线程执行。如果异常发生在 UI 线程,直接设置 Thread.setDefaultUncaughtExceptionHandler 即可捕获;但如果异常来自后台线程(如 Task、Service),则需确保错误处理逻辑回到 UI 线程:
- 在 handler 中用 Platform.runLater(() -> { ... }) 包裹 UI 更新(如弹 Toast、显示 Dialog)
- 禁止在 handler 里做耗时操作(如网络请求、文件写入),否则会卡住异常处理流程
- 推荐统一封装一个 showErrorDialog(String title, String msg) 方法,内部自动处理线程切换
- 若后台任务失败需清理状态(如关闭 loading 动画、重置按钮),也必须放在 runLater 中执行
共通要点:哪些事不能做
无论 Android 还是 JavaFX,在 UncaughtExceptionHandler 回调中都有严格限制:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 不能新建线程(Android 中会触发 StrictMode 报错;JavaFX 中可能引发并发问题)
- 不能调用 startActivity / show AlertDialog / new Stage() 等 UI 构建操作,除非确保已在正确线程
- 不能访问已销毁的上下文(Android)或已 dispose 的 Node(JavaFX),否则可能二次崩溃
- 避免无限递归或死循环——handler 本身也是异常触发点,逻辑必须简洁可靠
补充建议:让崩溃“可诊断”而非“不可见”
完全隐藏崩溃虽能提升表面稳定性,但会掩盖真实问题。更合理的做法是:
立即学习“Java免费学习笔记(深入)”;
- 保留 crash 日志(本地文件 + 时间戳 + 堆栈 + 设备信息)
- 集成 Firebase Crashlytics、Bugly 或自建上报服务,在 handler 中触发一次同步上报
- 对特定异常类型(如 ArithmeticException)可选择性忽略或降级处理,但需谨慎评估影响
- 上线前用 Monkey 测试 + 主动注入空指针/IO 异常,验证 handler 是否真正生效

















