【问题标题】:Android startActivity in BroadcastReceiver's onReceive functionBroadcastReceiver的onReceive函数中的Android startActivity
【发布时间】:2012-09-17 07:50:00
【问题描述】:

我的 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 是一种同步方法,可以像 WakefulIntentService 一样管理 WakeLock

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 的虚拟代码?

【问题讨论】:

  • 在BroadcastReciver的onRecive中设置alarmPopup.setFlags(Intent.FLAG_FROM_BACKGROUND)后试试

标签: android broadcastreceiver alarmmanager broadcast


【解决方案1】:

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

没有。该设备只是睡着了。 startActivity() 是一个异步操作。操作系统为AlarmManager 工作而持有的WakeLock(假设您确实在使用AlarmManager)将在onReceive() 返回时释放。在onReceive() 返回时,您的活动的onCreate() 将不会运行。因此,设备可能会在onReceive() 结束和您在onCreate() 中获取WakeLock 之间的时间窗口内进入休眠状态。

我该如何解决这个问题?

onReceive() 中获取WakeLock

【讨论】:

  • 感谢您的回答。实际上,当我写这个问题时,我希望你能回答我的问题,而且真的发生了! :) 所以你的意思是AlarmPopup的静态唤醒锁应该在BroadcastReceiver的onReceive中获取,并在AlarmPopup的OnDestroy中释放?
  • @Heejin:嗯,理想情况下,您不要长时间使用手册WakeLock 进行活动。如果您希望屏幕在活动处于前台时保持打开状态,我会使用 android:keepScreenOn 作为小部件。无论如何,我会尽快release() 手册WakeLock,最好早于onDestroy()。但是,是的,您可以在onReceive()acquire()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多