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 方法中,activity 保持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是一种同步方法,其管理WakeLock方式与WakefulIntentService一样。

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 分钟后。

似乎操作系统在创建过程中杀死了我的 AlarmPopup 活动,或者让活动的创建时间比startActivity实际调用的时间晚一点。

真正有趣的是,当出现上述问题时,有时会记录日志消息"Alarm popup acquires wake lock",有时甚至没有记录。我认为,在这种情况下,操作系统会在执行第一行或第二行onCreate方法时终止活动。

我怎么解决这个问题?

当另一个线程正在创建 AlarmPopup 活动时,我是否应该在 onReceive 结束时放置一些保持 CPU 的虚拟代码?

4

1 回答 1

4

似乎操作系统在创建过程中杀死了我的 AlarmPopup 活动,或者让活动的创建时间晚于实际调用 startActivity 的时间。

不,设备只是睡着了。startActivity()是一个异步操作。WakeLock操作系统为工作保留的(AlarmManager假设您确实在使用AlarmManager)将在onReceive()返回时释放。onCreate()您的活动将不会在onReceive()返回时运行。因此,设备可能会onReceive()在您获取WakeLockin onCreate().

我怎么解决这个问题?

获取WakeLockin onReceive()

于 2012-09-17T11:43:24.303 回答