WakefulBroadcastReceiver 学习笔记
2016-07-18 本文已影响3192人
ChuanDong
简介
WakefulBroadcastReceiver 是一种特殊的广播接收器. 它可以自动创建和管理唤醒锁 PARTIAL_WAKE_LOCK
来执行任务. 确保耗时任务执行完毕之前设备不会休眠.
WakefulBroadcastReceiver
收到广播后一般会启动 Service
(通常用 IntentService
来处理耗时任务), 同时确保设备在整个 Service
执行过程中保持唤醒状态. 不然的话, 对于耗时任务, 设备可能在你完成任务之前就休眠了.
注意点
-
通过
startWakefulService(Context, Intent)
启动Service
而不是startService()
.WakefulBroadcastReceiver
启动Service
的时候会自动创建唤醒锁, 并在Intent
附上唤醒锁的 ID 来判断这个唤醒锁. -
最后必须在
Service
中调用completeWakefulIntent(intent)
释放唤醒锁.
源码简析
先看一看启动服务的方法 startWakefulService()
public static ComponentName startWakefulService(Context context, Intent intent) {
synchronized (mActiveWakeLocks) {
....
// 这里在 intent 中加入了唤醒锁的 ID
intent.putExtra(EXTRA_WAKE_LOCK_ID, id);
ComponentName comp = context.startService(intent);
if (comp == null) {
return null;
}
// 获得设备的电源管理服务
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
// 这里获得了 PARTIAL_WAKE_LOCK 唤醒锁
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"wake:" + comp.flattenToShortString());
wl.setReferenceCounted(false);
wl.acquire(60*1000);
mActiveWakeLocks.put(id, wl);
return comp;
}
}
再看一看最后需要调用的方法 completeWakefulIntent()
public static boolean completeWakefulIntent(Intent intent) {
// 获得唤醒锁的 ID
final int id = intent.getIntExtra(EXTRA_WAKE_LOCK_ID, 0);
if (id == 0) {
return false;
}
synchronized (mActiveWakeLocks) {
// 通过 ID 找到唤醒锁
PowerManager.WakeLock wl = mActiveWakeLocks.get(id);
if (wl != null) {
// 释放唤醒锁
wl.release();
mActiveWakeLocks.remove(id);
return true;
}
return true;
}
}
如何使用
和使用 BroadcastReceiver
一样, 需要先在 AndroidManifest 定义接收器
<receiver android:name=".SimpleWakefulReceiver"></receiver>
然后继承 WakefulBroadcastReceiver
并实现 onReceive()
方法
public class SimpleWakefulReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, SimpleWakefulService.class);
// 启动 service 并保持设备唤醒状态直到调用 completeWakefulIntent()
startWakefulService(context, service);
}
}
在相应的 SimpleWakefulService
中进行耗时操作最后释放唤醒锁.
public class SimpleWakefulService extends IntentService {
public SimpleWakefulService() {
super("SimpleWakefulService");
}
@Override
protected void onHandleIntent(Intent intent) {
// 执行耗时任务
...
// 结束任务时释放唤醒锁
SimpleWakefulReceiver.completeWakefulIntent(intent);
}
}