WakefulBroadcastReceiver 學(xué)習(xí)筆記

簡介

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);    
    }
}

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容