Android应用能否自行检测自身过往崩溃并接收崩溃通知?
Android应用捕获自身崩溃及Service重启通知方案
Android应用可以捕获自身崩溃事件(包括Service崩溃),并触发通知或在重启后收集调试信息,以下是具体实现方案:
一、捕获全局崩溃(含Service)
通过自定义UncaughtExceptionHandler替换系统默认异常处理器,在崩溃发生时收集调试信息并触发通知。由于崩溃后进程会快速终止,建议先将日志写入本地存储,再通过轻量化逻辑发送通知,或依赖独立进程组件完成通知发送。
示例代码:
public class CrashHandler implements Thread.UncaughtExceptionHandler { private final Thread.UncaughtExceptionHandler defaultHandler; private final Context context; public CrashHandler(Context context) { this.context = context; defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); } @Override public void uncaughtException(Thread thread, Throwable throwable) { // 收集崩溃信息:栈轨迹、设备信息、时间戳等 String crashLog = collectCrashDetails(throwable); // 写入本地存储(内部文件或SharedPreferences) saveCrashLog(crashLog); // 发送崩溃通知 sendCrashAlert(crashLog); // 交给系统默认处理器终止进程 defaultHandler.uncaughtException(thread, throwable); } private String collectCrashDetails(Throwable throwable) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); throwable.printStackTrace(pw); // 追加设备信息 sw.append("\n设备型号:").append(Build.MODEL); sw.append("\n系统版本:").append(Build.VERSION.RELEASE); return sw.toString(); } private void saveCrashLog(String log) { try { File logFile = new File(context.getFilesDir(), "crash_records.txt"); FileWriter writer = new FileWriter(logFile, true); writer.write(new Date().toString() + "\n" + log + "\n\n"); writer.close(); } catch (IOException e) { e.printStackTrace(); } } private void sendCrashAlert(String log) { NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); // Android 8.0+ 创建通知渠道 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel("crash_channel", "崩溃告警", NotificationManager.IMPORTANCE_HIGH); notificationManager.createNotificationChannel(channel); } Notification notification = new NotificationCompat.Builder(context, "crash_channel") .setContentTitle("应用组件崩溃") .setContentText("Service发生异常,已保存日志") .setSmallIcon(R.drawable.ic_crash_alert) .setPriority(NotificationCompat.PRIORITY_HIGH) .build(); notificationManager.notify(1001, notification); } }
在Application初始化时设置异常处理器:
@Override public void onCreate() { super.onCreate(); CrashHandler crashHandler = new CrashHandler(this); Thread.setDefaultUncaughtExceptionHandler(crashHandler); }
二、监听Service重启并触发通知
若Service配置了前台属性(startForeground)或系统允许自动重启,可在Service的onCreate方法中检查本地崩溃日志,判断是否为崩溃后的重启,进而发送通知并处理日志。
示例代码:
@Override public void onCreate() { super.onCreate(); File crashLogFile = new File(getFilesDir(), "crash_records.txt"); if (crashLogFile.exists() && crashLogFile.length() > 0) { // 发送重启通知 sendRestartNotification(); // 上传或解析崩溃日志(可后台异步执行) processStoredCrashLog(); // 清除历史日志标记(可选) crashLogFile.delete(); } // 初始化Service业务逻辑 } private void sendRestartNotification() { NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel("restart_channel", "服务重启通知", NotificationManager.IMPORTANCE_DEFAULT); notificationManager.createNotificationChannel(channel); } Notification notification = new NotificationCompat.Builder(this, "restart_channel") .setContentTitle("Service已重启") .setContentText("此前发生崩溃,已完成自动恢复") .setSmallIcon(R.drawable.ic_restart) .build(); notificationManager.notify(1002, notification); }
三、关键注意事项
- Android 12及以上版本需申请
POST_NOTIFICATIONS权限,否则通知无法显示。 - 崩溃后的进程生命周期极短,通知发送逻辑需轻量化,避免耗时操作;若需确保通知发送成功,可使用独立进程的Service或BroadcastReceiver处理。
- 系统对进程重启的策略受版本、进程优先级影响,部分场景下Service崩溃后可能不会自动重启,建议结合
JobScheduler或WorkManager实现兜底的日志上报逻辑。
内容的提问来源于stack exchange,提问作者tse
相关产品推荐
相关产品推荐

