簡介
WakefulBroadcastReceiver 是一種特殊的廣播接收器. 它可以自動創(chuàng)建和管理喚醒鎖 PARTIAL_WAKE_LOCK 來執(zhí)行任務(wù). 確保耗時任務(wù)執(zhí)行完畢之前設(shè)備不會休眠.
WakefulBroadcastReceiver 收到廣播后一般會啟動 Service (通常用 IntentService 來處理耗時任務(wù)), 同時確保設(shè)備在整個 Service 執(zhí)行過程中保持喚醒狀態(tài). 不然的話, 對于耗時任務(wù), 設(shè)備可能在你完成任務(wù)之前就休眠了.
注意點
通過
startWakefulService(Context, Intent)啟動Service而不是startService().WakefulBroadcastReceiver啟動Service的時候會自動創(chuàng)建喚醒鎖, 并在Intent附上喚醒鎖的 ID 來判斷這個喚醒鎖.最后必須在
Service中調(diào)用completeWakefulIntent(intent)釋放喚醒鎖.
源碼簡析
先看一看啟動服務(wù)的方法 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;
}
// 獲得設(shè)備的電源管理服務(wù)
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;
}
}
再看一看最后需要調(diào)用的方法 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 并實現(xiàn) onReceive() 方法
public class SimpleWakefulReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, SimpleWakefulService.class);
// 啟動 service 并保持設(shè)備喚醒狀態(tài)直到調(diào)用 completeWakefulIntent()
startWakefulService(context, service);
}
}
在相應(yīng)的 SimpleWakefulService 中進行耗時操作最后釋放喚醒鎖.
public class SimpleWakefulService extends IntentService {
public SimpleWakefulService() {
super("SimpleWakefulService");
}
@Override
protected void onHandleIntent(Intent intent) {
// 執(zhí)行耗時任務(wù)
...
// 結(jié)束任務(wù)時釋放喚醒鎖
SimpleWakefulReceiver.completeWakefulIntent(intent);
}
}