【问题标题】:BroadcastReceiver, Service and Wakelock广播接收器、服务和唤醒锁
【发布时间】:2011-08-06 13:37:50
【问题描述】:

我在广播接收器中接收到一个意图,然后我开始服务以做更多的工作。现在如果设备处于睡眠状态并且发生这种情况怎么办,我是否必须获得唤醒锁(AlarmManger?),我为什么需要它? 如果设备在没有唤醒锁的情况下进入睡眠状态,我的服务会停止运行吗?

【问题讨论】:

    标签: android wakelock android-wake-lock


    【解决方案1】:

    现在如果设备处于睡眠状态并且发生这种情况,我是否必须获得唤醒锁(AlarmManger?),为什么需要它?

    如果设备一开始就处于睡眠状态,您将不会“在广播接收器中接收到意图”,因为设备处于睡眠状态。

    我是否必须获得 Wakelock(AlarmManger?),我为什么需要它?

    你不需要它,除非你想确保设备在你完成一些工作时保持运行。

    如果设备在没有唤醒锁的情况下进入睡眠状态,我的服务是否会停止运行。

    是的。

    【讨论】:

    • 对于第一部分,我的意思是我会收到来自 C2DM 的意图,我猜你可以在设备处于睡眠状态时收到它。然后我想运行一项服务,我想我必须获得唤醒锁才能保持运行。这些假设是否正确?
    • @Fevos:“我的意思是我会收到来自 C2DM 的意图,我猜你可以在设备处于睡眠状态时收到它。” -- 是的,C2DM 使用基于无线数据的套接字连接 (AFAIK),该连接上的传入数据包将短暂地唤醒设备。 “然后我想运行一项服务,我想我必须让唤醒锁保持运行。这些假设是否正确?” -- 是的,你会想要自己的WakeLock。完成后一定要释放它。
    • "如果设备一开始就处于休眠状态,您将不会“在广播接收器中接收到意图”,因为设备处于休眠状态。"这是在哪里记录的?
    • @MarianPaździoch:“这是在哪里记录的?” - 我怀疑它是否被具体记录,部分原因是它很明显。如果 CPU 不执行指令,则不会处理任何人的广播Intent。欢迎您阅读PowerManagerPowerManager.WakeLock 上的文档以了解有关CPU 状态的更多信息。
    • @CommonsWare 我不会在 Android 的上下文中使用 OBVIOUS 这个词 :)。因此,如果 BroadcastReceiver 保留设备 PARTIAL_WAKE_LOCK 是显而易见的,那么 IntentService 也保留设备 PARTIAL_WAKE_LOCK 是否也很明显?
    【解决方案2】:
    public class WakeLockManager extends BroadcastReceiver {
    
        private static WakeLock mWakeLock;
        private String LCLT;
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Consts.WAKELOCK_INTENT)) {
                Log.v("wakelock", "GOT THE wakelock INTENT");
                boolean on = intent.getExtras().getBoolean("on");
                if (mWakeLock == null) {
                    PowerManager pm = (PowerManager) context
                            .getSystemService(Context.POWER_SERVICE);
                    mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                            "Breeze WakeLock");
                }
                if (on) {
                    if (!mWakeLock.isHeld()) {
                        mWakeLock.acquire();
                        Log.v("wakelock", "acquiring wakelock");
                    }
                } else {
                    if (mWakeLock.isHeld()) {
                        Log.v("wakelock", "releasing wakelock");
                        mWakeLock.release();
                    }
                    mWakeLock = null;
                }
            }
        }
    }
    

    看看上面的代码..把它放在一个单独的类文件中,并在你的清单中为一些自定义意图定义它......现在这个类将响应一个自定义意图......只需广播那个意图和您可以在整个应用程序中打开或关闭唤醒锁,因为唤醒锁是静态的。就像这样:

    public void setWakeup(boolean status) {
        Intent wakelock_Intent = new Intent(CUSTOM_INTENT);
        wakelock_Intent.putExtra("on", status);
        this.sendBroadcast(wakelock_Intent);
    }
    

    上述内容将在您的警报管理器代码中定义以便安排调用

    【讨论】:

    • 你确定当接收器class被卸载时这个“静态锁”不会被清除吗?请参阅:stackoverflow.com/questions/6299283/…
    • 我假设对象不会被垃圾收集,因为这不是匿名广播接收器。如果我自己分配这个对象并保持对它的硬引用,为什么它会被系统释放?这是一个有趣的话题,请指教。
    【解决方案3】:

    看起来 Android 的原生 WakefulBroadcastReceiver 将是您的完美解决方案。需要扩展这个而不是常规的 BroadcastReceiver 并以“清醒”的方式在 onReceive() 中启动服务:

    startWakefulService(context, service);
    

    并在服务的 onHandleIntent() 中表明您的工作已完成,调用

    MyWakefulReceiver.completeWakefulIntent(intent);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多