在IntentService中获取部分唤醒锁定



我的IntentService从两个地方被触发,无论是通过警报还是通过活动,由于持续时间与它需要从网络获取的数据量有关,根据我的理解,我需要保持部分唤醒锁定。

这是我的实现:

@Override
protected void onHandleIntent(Intent intent) {
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WakeLock");
try {
wakeLock.setReferenceCounted(false);
wakeLock.acquire(3600000); 
///other code here
}
catch{
}
finally{ 
if (wakeLock.isHeld()) {
wakeLock.release();
}
}

我的问题是:这是否足够好?finally会确保在任何情况下都释放唤醒锁吗?据我所知,onHandleIntent一个接一个地处理意图,因此同时拥有两个意图/2个唤醒锁没有风险。

后期编辑:

IntentService有两种调用方式:

  1. 来自我的活动,如

    startService(new Intent(context, MyService.class).putExtra()..);

2来自使用PendingIntent 触发的Alarm

PendingIntent pendingIntent = PendingIntent.getService(context, someId, myServiceIntent, PendingIntent.FLAG_UPDATE_CURRENT);

当从Alarm运行时,服务是否有足够的时间获取唤醒锁定?

是否需要保持唤醒锁定与Service的工作量无关——理论上,即使工作量很小,设备也可以进入睡眠状态。

只有当您绝对必须确保设备在Service运行时无法休眠时,才应考虑唤醒锁定。像这样的病例非常罕见。一些例子:

  • 闹钟应用程序(即使设备处于睡眠状态也需要唤醒您)
  • 实时消息应用程序(即使设备处于睡眠状态,也需要通知您新消息)

大多数应用程序都没有如此严格的时间要求。例如,以下不是使用唤醒锁的好理由:

  • 定期与服务器同步数据(应延迟到设备唤醒)
  • 在地图上显示当前用户的位置(可以在设备唤醒时获得;但监控用户整个路线的应用程序需要唤醒锁定)

如果您确实需要确保设备在Service执行期间不会休眠,那么您需要获取唤醒锁(几种类型之一)。让我们假设这里就是这样。

您希望能够从应用程序的UI(Activity)启动"唤醒"Service,并使用AlarmManager

从UI开始

由于设备应该是完全唤醒的,以便用户与UI交互,您可以放心地假设,如果您启动Service以响应UI交互,它将有机会获得唤醒锁定(但在Service启动后立即执行)。

您的解决方案涵盖了这种情况。

AlarmManager开始

不幸的是,当AlarmManager启动Service时,无法保证(至少没有书面保证)它将保持唤醒锁并允许Service获取自己的唤醒锁。这意味着设备可以在警报响起后进入睡眠状态,但在您的Service有机会获得唤醒锁定之前。

这意味着在这种情况下,您的解决方案将"中断"。

AlarmManager将帮助您进行唤醒锁定的唯一记录方案涉及广播:

报警管理器在报警时保持CPU唤醒锁定receiver的onReceive()方法正在执行。这保证了在您处理完广播之前,手机不会休眠。一旦onReceive()返回,报警管理器就会释放此唤醒锁。这意味着在某些情况下,手机会在onReceive()方法完成。如果你的闹钟响了Context.startService(),手机可能会休眠在启动所请求的服务之前。为了防止这种情况BroadcastReceiver和Service将需要实现单独的唤醒锁定策略,以确保手机继续运行,直到服务可用。

这就是WakefulBroadcastReceiver非常方便的地方。

请注意,如果使用此方案,则不需要为"UI启动"情况支持不同的方案——在这两种情况下使用相同的方法。

你可能还想看看这个由@CommonsWare开发的库(不过我自己没有用过)。

最新更新