在 Service 中使用 while(true) 迴圈配合 Thread.sleep() 會導致 ANR(應用程式無回應)且無法正確控制生命週期。
public class RepService extends Service {
@Override public IBinder onBind(Intent intent) { return null; }
// 錯誤:while(true) 會阻塞主執行緒,導致 ANR
while(true) {
Thread timer = new Thread() {
public void run() {
try { sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); }
}
};
timer.start();
}
}
public class RepService extends Service {
private Timer timer;
@Override
public void onCreate() {
super.onCreate();
timer = new Timer();
// 立即執行,每 5 分鐘重複一次 (300000 毫秒)
timer.schedule(new TimerTask() {
@Override public void run() {
// 執行週期性任務
doPeriodicWork();
}
}, 0, 5 * 60 * 1000); // 5 分鐘
}
private void doPeriodicWork() {
// 如果需要更新 UI,必須切回主執行緒
new Handler(Looper.getMainLooper()).post(() -> updateUI());
}
@Override
public void onDestroy() {
timer.cancel(); // 釋放資源
super.onDestroy();
}
@Override public IBinder onBind(Intent intent) { return null; }
}
更省電、系統級排程,適合精確或非精確週期任務:
// 在 Service 或 Application 啟動時設定
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, PeriodicReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_IMMUTABLE);
// 每 5 分鐘觸發一次 (非精確,省電)
am.setInexactRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), 5 * 60 * 1000, pi);
// 接收器
public class PeriodicReceiver extends BroadcastReceiver {
@Override public void onReceive(Context context, Intent intent) {
// 執行任務,建議啟動 IntentService 或 JobIntentService
}
}
Android Jetpack WorkManager 是目前推薦的延遲任務框架:
PeriodicWorkRequest work = new PeriodicWorkRequest.Builder(
MyWorker.class, 15, TimeUnit.MINUTES) // 最小間隔 15 分鐘
.build();
WorkManager.getInstance(context).enqueue(work);
// Worker 類別
public class MyWorker extends CoroutineWorker {
public MyWorker(@NonNull Context context, @NonNull WorkerParameters params) {
super(context, params);
}
@NonNull @Override public Result doWork() {
// 背景執行緒執行任務
return Result.success();
}
}
| 方案 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|
| Timer | 應用內短週期、非精確 | 簡單、輕量 | 進程死掉即停止 |
| AlarmManager | 系統級排程、需喚醒裝置 | 可跨進程、精確控制 | API 19+ 非精確、Doze 模式限制 |
| WorkManager | 可延遲、需保證執行、支援約束 | 生命週期感知、跨版本相容 | 最小間隔 15 分鐘 |