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

Android 7.1(SDK25)工业应用崩溃自动重启及保活问题咨询

针对Android 7.1(SDK 25)工业应用的自动重启解决方案

针对你遇到的无控崩溃无法重启、Service检测重启时NPE的问题,以下是适配SDK 25的可行方案,核心思路是全局异常捕获处理崩溃+前台Service持续监控进程状态,且全程避免依赖Activity引用导致的空指针问题。

1. 全局异常捕获(处理无控崩溃)

通过设置全局UncaughtExceptionHandler,捕获所有未处理的异常,在崩溃时直接触发应用重启逻辑,无需依赖Activity生命周期。

代码实现(在自定义Application类中)

public class IndustrialApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        initCrashHandler();
    }

    private void initCrashHandler() {
        Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
            // 可选:记录崩溃日志到本地或服务器
            Log.e("CrashMonitor", "应用崩溃: ", throwable);
            
            // 执行重启逻辑
            restartApplication();
        });
    }

    private void restartApplication() {
        Intent restartIntent = new Intent(this, MainActivity.class);
        // 清除旧任务栈,启动新的主Activity
        restartIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        
        PendingIntent pendingIntent = PendingIntent.getActivity(
                this,
                0,
                restartIntent,
                PendingIntent.FLAG_UPDATE_CURRENT
        );

        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        if (alarmManager != null) {
            // 延迟1秒重启,给系统留出进程清理时间
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000, pendingIntent);
        }

        // 强制终止当前进程
        android.os.Process.killProcess(android.os.Process.myPid());
        System.exit(1);
    }
}

2. 前台Service监控(应对意外进程被杀)

将Service设置为前台服务,提升系统优先级避免被轻易回收,定时检测应用进程是否存活,若进程消失则直接重启应用,全程使用ApplicationContext操作,避免持有Activity引用。

前台Service代码实现

public class KeepAliveService extends Service {
    private static final int NOTIFICATION_ID = 1001;
    private Handler checkHandler;
    private Runnable checkRunnable;
    private static final long CHECK_INTERVAL = 5000; // 每5秒检测一次

    @Override
    public void onCreate() {
        super.onCreate();
        // 启动前台通知,确保Service不被系统回收
        startForeground(NOTIFICATION_ID, createKeepAliveNotification());
        
        initProcessChecker();
    }

    private Notification createKeepAliveNotification() {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_service_notify)
                .setContentTitle("工业应用监控中")
                .setContentText("应用持续运行保障")
                .setPriority(NotificationCompat.PRIORITY_LOW);

        // 兼容Android O及以上版本的通知渠道(SDK25无需,但不影响)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(
                    "keep_alive_channel",
                    "应用保活",
                    NotificationManager.IMPORTANCE_LOW
            );
            NotificationManager manager = getSystemService(NotificationManager.class);
            if (manager != null) {
                manager.createNotificationChannel(channel);
                builder.setChannelId("keep_alive_channel");
            }
        }

        return builder.build();
    }

    private void initProcessChecker() {
        checkHandler = new Handler(Looper.getMainLooper());
        checkRunnable = () -> {
            if (!isAppProcessAlive()) {
                restartApplication();
            }
            checkHandler.postDelayed(checkRunnable, CHECK_INTERVAL);
        };
        checkHandler.post(checkRunnable);
    }

    // 检测当前应用进程是否存活且处于前台
    private boolean isAppProcessAlive() {
        ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        if (activityManager == null) return false;

        List<ActivityManager.RunningAppProcessInfo> processList = activityManager.getRunningAppProcesses();
        if (processList == null || processList.isEmpty()) return false;

        String packageName = getPackageName();
        for (ActivityManager.RunningAppProcessInfo processInfo : processList) {
            if (processInfo.processName.equals(packageName) 
                && processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                return true;
            }
        }
        return false;
    }

    private void restartApplication() {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (checkHandler != null && checkRunnable != null) {
            checkHandler.removeCallbacks(checkRunnable);
        }
        // 若Service被意外销毁,尝试重启自身
        startService(new Intent(this, KeepAliveService.class));
    }
}

3. Manifest配置要点

<application
    android:name=".IndustrialApp"
    ...>
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service
        android:name=".KeepAliveService"
        android:stopWithTask="false" /> <!-- 应用从最近任务移除时不停止Service -->

    <!-- 所需权限 -->
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
</application>

关键注意事项

  • 全程使用ApplicationContext启动组件,避免持有Activity的WeakReference,彻底解决NPE问题;
  • 前台Service的通知设置为低优先级,不会干扰工业场景使用;
  • stopWithTask="false"确保应用被用户从最近任务列表移除后,Service仍能继续运行;
  • 全局异常捕获覆盖大部分无控崩溃场景,前台Service的定时检测则能应对系统主动杀进程的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:01:08