首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android Service 未捕獲異常停止後自動重啟:START_STICKY 機制

     編輯:程式設計綜合問答

Service 執行緒拋出未捕獲異常導致進程崩潰,系統依 onStartCommand 回傳值決定是否重啟。回傳 START_STICKY 可讓系統在記憶體允許時重建 Service 並呼叫 onStartCommand(null, 0, 0)。

核心修正:回傳 START_STICKY


@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // 初始化工作...
    return START_STICKY; // 關鍵:告訴系統崩潰後重啟
}

完整 Service 範本


public class UpdateService extends Service {
    private Timer timer;
    private static final long INTERVAL = 60_000;

    @Override
    public void onCreate() {
        super.onCreate();
        startPolling();
    }

    private void startPolling() {
        timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                try {
                    // 網路請求、資料庫操作等風險工作
                    doWork();
                } catch (Exception e) {
                    Log.e("UpdateService", "Polling error", e);
                    // 關鍵:捕獲異常防止執行緒死亡
                    // 若想觸發系統重啟,可拋出 RuntimeException
                    // throw new RuntimeException(e);
                }
            }
        }, 0, INTERVAL);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

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

START_STICKY vs START_NOT_STICKY vs START_REDELIVER_INTENT

常數重啟行為Intent 遞送適用場景
START_STICKY是onStartCommand(null, 0, 0)長期運行、狀態可自行恢復的服務(音樂播放、定時同步)
START_NOT_STICKY否無一次性工作、由呼叫端控制生命週期
START_REDELIVER_INTENT是重傳最後 Intent需保證完成的關鍵任務(上傳、下載)

未捕獲異常處理最佳實踐


// 方案一:執行緒層級捕獲(推薦)
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
    Log.e("Service", "Uncaught exception in " + thread.getName(), throwable);
    // 可選:上報崩潰分析平台
});

// 方案二:TimerTask 內部 try-catch(如上例)
// 方案三:ExecutorService + Future.get() 捕獲

現代替代:WorkManager / Foreground Service

  • WorkManager:延遲、周期性、有條件執行,系統自動管理生命週期、電池優化、重試策略,適合定時輪詢。
  • Foreground Service:Android 8+ 後台限制下必須前台運行,配合 START_STICKY 更穩健。

Manifest 註冊別忘


 

設定 START_STICKY 並妥善捕獲執行緒異常,即能讓 Service 在異常崩潰後自動復原,保障長期任務連續性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved