Android應用程序 --- WakeLock 保持後臺喚醒狀態

一些手機app(如微信、QQ等)有新消息來到達,手機屏幕即便在鎖屏狀態下也會亮起,並提示用戶有新消息。可是,通常狀況下手機鎖屏後,Android系統爲了省電以及減小CPU消耗,在一段時間後會使系統進入休眠狀態,這時,Android系統中CPU會保持在一個相對較低的功耗狀態,而收到新消息一定有網絡請求,而網絡請求是消耗CPU的操做,那麼如何在鎖屏狀態乃至系統進入休眠後,仍然保持系統的網絡狀態以及經過程序喚醒手機呢?答案就是Android中的WakeLock機制。


官方對於WakeLock的解釋:
    PowerManager:This class gives you control of the power state of the device.
    PowerManager.WakeLock: lets you say that you need to have the device on.



Android 系統支持應用程序及服務在待機前保存程序運行狀態,如待機前關閉文件讀寫、usb 操做、暫停音樂播放;也支持喚醒後的程序狀態恢復,如恢復打開文件進行讀寫操做,恢復 usb 操做、恢復音樂播放等。這些狀態的保存和恢復功能能夠保證系統在待機喚醒後能正常工做。 java

主要提供兩種方式: android

一、待機廣播消息和喚醒廣播消息。
二、Wakelock 鎖機制。

   
分爲兩個部分說明一下:

一、android 系統待機處理機制

待機廣播消息和喚醒廣播消息
系統在 PowerManagerService 類中註冊了 2 個廣播分別用於待機前和喚醒後發送。

void initInThread(){
//喚醒後:
mScreenOnIntent=newIntent(Intent.ACTION_SCREEN_ON);//喚醒後發送
mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
//待機前:
mScreenOffIntent=newIntent(Intent.ACTION_SCREEN_OFF);//待機時發送
mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
}

這裏順帶說明一下廣播接收的優先級問題:
接收者按照在 Manifest.xml 文件中設置的接收順序依次接收Intent,順序執行的,接收的優先級能夠在系統配置文件中設置:
聲明在intent-filter元素的android:priority 屬性中,數值越大優先級別越高,其取值範圍爲-1000到1000。固然也能夠在調用IntentFilter對象的setPriority()方法進行設置

Wakelock 鎖機制:
應用程序能夠經過申請 wakelock 鎖的機制來對系統是否待機做出投票,當有任何一個應用申請了 wakelock 鎖,待機時沒有釋放掉,系統是不會進入待機的,直到全部應用的 wakelock 鎖都釋放掉了,纔會進入待機。


二、應用程序使用方法:

實例代碼: 微信

  1. <span style="font-family: SimSun;"> private WakeLock wakeLock = null
  2.  
  3.     /**
  4.      * 獲取電源鎖,保持該服務在屏幕熄滅時仍然獲取CPU時,保持運行
  5.      */ 
  6.     private void acquireWakeLock() { 
  7.         if (null == wakeLock) { 
  8.             PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 
  9.             wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK 
  10.                     | PowerManager.ON_AFTER_RELEASE, getClass() 
  11.                     .getCanonicalName()); 
  12.             if (null != wakeLock) { 
  13.                 Log.i(TAG, "call acquireWakeLock"); 
  14.                 wakeLock.acquire(); 
  15.             } 
  16.         } 
  17.     } 
  18.  
  19.     // 釋放設備電源鎖 
  20.     private void releaseWakeLock() { 
  21.         if (null != wakeLock && wakeLock.isHeld()) { 
  22.             Log.i(TAG, "call releaseWakeLock"); 
  23.             wakeLock.release(); 
  24.             wakeLock = null
  25.         } 
  26.     }</span> 

 private WakeLock wakeLock = null; /** * 獲取電源鎖,保持該服務在屏幕熄滅時仍然獲取CPU時,保持運行 */ private void acquireWakeLock() { if (null == wakeLock) { PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, getClass() .getCanonicalName()); if (null != wakeLock) { Log.i(TAG, "call acquireWakeLock"); wakeLock.acquire(); } } } // 釋放設備電源鎖 private void releaseWakeLock() { if (null != wakeLock && wakeLock.isHeld()) { Log.i(TAG, "call releaseWakeLock"); wakeLock.release(); wakeLock = null; } }


WakeLock 類型以及說明:
    PARTIAL_WAKE_LOCK:保持CPU 運轉,屏幕和鍵盤燈有多是關閉的。
    SCREEN_DIM_WAKE_LOCK:保持CPU 運轉,容許保持屏幕顯示但有多是灰的,容許關閉鍵盤燈
    SCREEN_BRIGHT_WAKE_LOCK:保持CPU 運轉,容許保持屏幕高亮顯示,容許關閉鍵盤燈
    FULL_WAKE_LOCK:保持CPU 運轉,保持屏幕高亮顯示,鍵盤燈也保持亮度
    ACQUIRE_CAUSES_WAKEUP:強制使屏幕亮起,這種鎖主要針對一些必須通知用戶的操做.
    ON_AFTER_RELEASE:當鎖被釋放時,保持屏幕亮起一段時間


最後 AndroidManifest.xml 聲明權限:
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.DEVICE_POWER"/>


應用程序中若是要在待機前保存數據狀態的話,要保證此過程當中不會進入待機。能夠在 onResume() 或者 onStart() 中申請 wakelock 鎖,即調用acquireWakeLock()方法。

在 onPause() 或者 onDistroy() 中處理應用待機後再釋放掉 wakelock 鎖,此時調用releaseWakeLock()方法 網絡


最後一點須要注意下: app

另外WakeLock的設置是 Activiy 級別的,不是針對整個Application應用的。因此application下有多個activity必定須要注意下! ui

相關文章
相關標籤/搜索