痛點:BroadcastReceiver 無 getSystemService() 方法,直接調用編譯報錯。
public class MyReceiver extends BroadcastReceiver {
private Context context; // 成員變量持有
@Override
public void onReceive(Context context, Intent intent) {
this.context = context; // 保存
// 立即使用或啟動 Service/線程中使用
setAlarm(context);
}
private void setAlarm(Context ctx) {
AlarmManager am = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
// ...
}
}
onReceive 的 Context 是 ReceiverRestrictedContext,**僅在 onReceive 存活期間有效**。onReceive 後異步使用(如線程、Handler),**必須傳遞 Application Context**:context.getApplicationContext(),避免內存洩漏。onReceive 執行超過 10 秒會 ANR,鬧鐘設置邏輯應極快,或啟動 IntentService/JobIntentService 異步處理。public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 1. 獲取 Application Context 長期持有
Context appCtx = context.getApplicationContext();
// 2. 啟動 Service 異步處理鬧鐘邏輯
Intent serviceIntent = new Intent(appCtx, AlarmService.class);
serviceIntent.putExtra("action", intent.getAction());
ContextCompat.startForegroundService(appCtx, serviceIntent);
}
}
// AlarmService extends IntentService { ... }
牢記:BroadcastReceiver 靠傳入 Context 訪問系統服務,異步場景必轉 Application Context。