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