BroadcastReceiver の onReceive 関数に次のコードがあります。
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action == null) return;
if (action.equals(ACTION_ALARM)) {
Intent alarmPopup = new Intent(context, AlarmPopup.class);
int vibrateDuration = context.getSharedPreferences(PREF, 0)
.getInt(VIBRATE_DURATION, DEFAULT_VIBRATE_DURATION)
alarmPopup.putExtra(VIBRATE_DURATION, vibrateDuration);
alarmPopup.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(alarmPopup);
}
}
このコードAlarmPopup
は、アラーム マネージャのブロードキャストを受信すると、アクティビティを開始します。AlarmPopup アクティビティが開始されると、通常のアラーム メッセージが表示され、vibrateDuration
通過中に振動しますIntent#putExtra
。
AlarmPopup の onCreate メソッドではWakeLock
、デバイスの電源をオンにし続けるためにアクティビティが保持されます。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
wl = getLock(this);
if (!wl.isHeld()) {
Log.d(PREF, "Alarm popup acquires wake lock");
wl.acquire();
thread.run();
}
.
.
.
}
getLock
WakefulIntentServiceWakeLock
と同様に管理する同期メソッドです。
private static volatile PowerManager.WakeLock wlStatic = null;
synchronized private static PowerManager.WakeLock getLock(Context context) {
if (wlStatic == null) {
PowerManager mgr = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wlStatic = mgr.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, PREF);
wlStatic.setReferenceCounted(true);
}
return wlStatic;
}
ここで問題があります:context.startActivity(alarmPopup)
が呼び出されても、startActivity
めったにアクティビティを開始しないか、時間どおりに開始されません。通常は 1 ~ 2 分後に発生します。
OS が私の AlarmPopup アクティビティを作成途中で強制終了するか、startActivity
実際に呼び出された時間よりも少し遅れてアクティビティを作成するようです。
本当に興味深いのは、上記の問題が発生した場合、ログ メッセージ"Alarm popup acquires wake lock"
が記録される場合と記録されない場合があることです。この場合、OS はメソッドの 1 行目または 2 行目を実行している間にアクティビティを強制終了すると思いますonCreate
。
どうすればこの問題を解決できますか?
AlarmPopup アクティビティが別のスレッドによって作成されている間、onReceive の最後に CPU を保持するダミー コードを配置する必要がありますか?