1

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();
    }
    .
    .
    .
}

getLockWakefulIntentServiceWakeLockと同様に管理する同期メソッドです。

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 を保持するダミー コードを配置する必要がありますか?

4

1 に答える 1

4

OSがAlarmPopupアクティビティを作成中に強制終了するか、startActivityが実際に呼び出された時間より少し遅れてアクティビティを作成させたようです。

いいえ。デバイスは単にスリープ状態になりました。startActivity()非同期操作です。作業のWakeLockためにOSが保持していたAlarmManagerもの(実際に使用していると仮定AlarmManager)は、戻ったときに解放されonReceive()ます。あなたの活動のは、戻るonCreate()までに実行されていません。したがって、デバイスは、の終了から取得onReceive()までの時間枠内でスリープ状態になる可能性があります。onReceive()WakeLockonCreate()

どうすればこの問題を解決できますか?

で取得WakeLockonReceive()ます。

于 2012-09-17T11:43:24.303 に答える