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

如何通过前台/后台Service重启崩溃的Android应用?

解决Android应用崩溃后自动重启的问题

核心问题原因

你当前的代码只有在Service所属应用前台时才能启动目标App,本质是Android 10(API 29)及以上系统对后台启动Activity的严格限制:后台进程默认不允许启动Activity,只有满足特定条件(如前台Service绑定可见通知、应用处于白名单等)时才能触发。


解决方案1:完善前台Service,满足后台启动条件

首先确保你的前台Service完全符合系统要求,同时加入App运行状态判断避免重复启动:

  1. 添加必要权限
    在AndroidManifest.xml中声明:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Android 10+ 后台启动Activity需声明,部分厂商可能额外要求 -->
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
  1. 完善前台Service代码
    补全startForeground调用(必须显示通知),添加App运行状态检测,优化循环逻辑:
public class RestartService extends Service {
    private static final int NOTIFICATION_ID = 1001;
    private WakeLock wakeLock;
    private boolean isRunning = true;

    @Override
    public void onCreate() {
        super.onCreate();
        // 启动前台通知,必须调用否则Service会被系统回收
        startForeground(NOTIFICATION_ID, createNotification());
        
        // 获取WakeLock保持CPU唤醒
        PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "RestartService::WakeLock");
        wakeLock.acquire();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(() -> {
            while (isRunning) {
                try {
                    // 检查目标App是否在运行
                    if (!isAppRunning("app.tester.com")) {
                        // 启动目标App
                        Intent launchIntent = getPackageManager().getLaunchIntentForPackage("app.tester.com");
                        if (launchIntent != null) {
                            launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            // Android 10+ 额外添加FLAG_ACTIVITY_REORDER_TO_FRONT避免重复创建任务栈
                            launchIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                            startActivity(launchIntent);
                        }
                    }
                    // 每隔5秒检查一次,避免频繁操作
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    break;
                }
            }
        }).start();
        return START_STICKY;
    }

    // 判断App是否在运行(检测进程+任务栈,更准确)
    private boolean isAppRunning(String packageName) {
        ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        // 检测进程是否存活
        for (ActivityManager.RunningAppProcessInfo processInfo : activityManager.getRunningAppProcesses()) {
            if (packageName.equals(processInfo.processName)) {
                return true;
            }
        }
        // 检测任务栈中是否有该App的Activity
        for (ActivityManager.RunningTaskInfo taskInfo : activityManager.getRunningTasks(Integer.MAX_VALUE)) {
            if (packageName.equals(taskInfo.topActivity.getPackageName())) {
                return true;
            }
        }
        return false;
    }

    // 创建前台通知
    private Notification createNotification() {
        NotificationChannel channel = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            channel = new NotificationChannel("RestartServiceChannel", "App重启服务", NotificationManager.IMPORTANCE_LOW);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }

        return new NotificationCompat.Builder(this, "RestartServiceChannel")
                .setContentTitle("App重启服务")
                .setContentText("正在监控目标App状态")
                .setSmallIcon(R.drawable.ic_notification)
                .setPriority(NotificationCompat.PRIORITY_LOW)
                .build();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        isRunning = false;
        if (wakeLock != null && wakeLock.isHeld()) {
            wakeLock.release();
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}
  1. 申请电池优化豁免
    Android 8+的电池优化会限制后台Service运行,需要引导用户将你的Service应用加入电池优化白名单:
// 检查是否在白名单中
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (!powerManager.isIgnoringBatteryOptimizations(getPackageName())) {
    Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
    intent.setData(Uri.parse("package:" + getPackageName()));
    startActivity(intent);
}

解决方案2:修改目标App,自崩溃后重启(更可靠)

如果能修改崩溃的目标App,建议在App内部实现崩溃监听+自启动,避免跨应用权限问题:

  1. 设置全局异常处理器
    在Application类中初始化:
public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
            // 记录崩溃日志
            Log.e("Crash", "App crashed", throwable);
            
            // 启动前台Service重启App
            Intent restartIntent = new Intent(this, RestartSelfService.class);
            startForegroundService(restartIntent);
            
            // 终止当前进程
            android.os.Process.killProcess(android.os.Process.myPid());
            System.exit(1);
        });
    }
}
  1. 实现自重启Service
    Service逻辑类似方案1,启动后延迟几秒再启动App的Launcher Activity:
public class RestartSelfService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
        startForeground(1002, createNotification());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(() -> {
            try {
                // 延迟3秒重启,给系统清理时间
                Thread.sleep(3000);
                Intent launchIntent = getPackageManager().getLaunchIntentForPackage(getPackageName());
                if (launchIntent != null) {
                    launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                    startActivity(launchIntent);
                }
                stopSelf();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        return START_NOT_STICKY;
    }

    // 省略通知创建和其他生命周期方法,参考方案1实现
}

关键注意事项

  • 厂商定制ROM限制:小米、华为、vivo等厂商有自己的后台管控策略,需要引导用户将你的应用加入"自启动白名单"和"后台运行权限"。
  • Android 12+ 前台Service限制:API 31+要求前台Service必须与用户可见组件关联,或属于特定类型(如媒体、定位等),需确保Service类型符合要求。

内容的提问来源于stack exchange,提问作者Shazer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 08:22:49