一些手機(jī)app(如微信、QQ等)有新消息來(lái)到達(dá)秀又,手機(jī)屏幕即使在鎖屏狀態(tài)下也會(huì)亮起,并提示用戶(hù)有新消息贬芥。但是吐辙,一般情況下手機(jī)鎖屏后,Android系統(tǒng)為了省電以及減少CPU消耗蘸劈,在一段時(shí)間后會(huì)使系統(tǒng)進(jìn)入休眠狀態(tài)昏苏,這時(shí),Android系統(tǒng)中CPU會(huì)保持在一個(gè)相對(duì)較低的功耗狀態(tài)威沫,而收到新消息必定有網(wǎng)絡(luò)請(qǐng)求贤惯,而網(wǎng)絡(luò)請(qǐng)求是消耗CPU的操作,那么如何在鎖屏狀態(tài)乃至系統(tǒng)進(jìn)入休眠后棒掠,仍然保持系統(tǒng)的網(wǎng)絡(luò)狀態(tài)以及通過(guò)程序喚醒手機(jī)呢孵构?答案就是Android中的WakeLock機(jī)制。
官方對(duì)于WakeLock的解釋?zhuān)?/p>
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 系統(tǒng)支持應(yīng)用程序及服務(wù)在待機(jī)前保存程序運(yùn)行狀態(tài)烟很,如待機(jī)前關(guān)閉文件讀寫(xiě)浦译、usb 操作、暫停音樂(lè)播放溯职;也支持喚醒后的程序狀態(tài)恢復(fù)精盅,如恢復(fù)打開(kāi)文件進(jìn)行讀寫(xiě)操作,恢復(fù) usb 操作谜酒、恢復(fù)音樂(lè)播放等叹俏。這些狀態(tài)的保存和恢復(fù)功能可以保證系統(tǒng)在待機(jī)喚醒后能正常工作。
主要提供兩種方式:
1僻族、待機(jī)廣播消息和喚醒廣播消息粘驰。
2屡谐、Wakelock 鎖機(jī)制。
分為兩個(gè)部分說(shuō)明一下:
1蝌数、android 系統(tǒng)待機(jī)處理機(jī)制
待機(jī)廣播消息和喚醒廣播消息
系統(tǒng)在 PowerManagerService 類(lèi)中注冊(cè)了 2 個(gè)廣播分別用于待機(jī)前和喚醒后發(fā)送愕掏。
void initInThread(){
//喚醒后:
mScreenOnIntent=newIntent(Intent.ACTION_SCREEN_ON);//喚醒后發(fā)送
mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
//待機(jī)前:
mScreenOffIntent=newIntent(Intent.ACTION_SCREEN_OFF);//待機(jī)時(shí)發(fā)送
mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
}
這里順帶說(shuō)明一下廣播接收的優(yōu)先級(jí)問(wèn)題:
接收者按照在 Manifest.xml 文件中設(shè)置的接收順序依次接收Intent,順序執(zhí)行的顶伞,接收的優(yōu)先級(jí)可以在系統(tǒng)配置文件中設(shè)置:
聲明在intent-filter元素的android:priority 屬性中饵撑,數(shù)值越大優(yōu)先級(jí)別越高,其取值范圍為-1000到1000唆貌。當(dāng)然也可以在調(diào)用IntentFilter對(duì)象的setPriority()方法進(jìn)行設(shè)置
Wakelock 鎖機(jī)制:
應(yīng)用程序可以通過(guò)申請(qǐng) wakelock 鎖的機(jī)制來(lái)對(duì)系統(tǒng)是否待機(jī)作出投票滑潘,當(dāng)有任何一個(gè)應(yīng)用申請(qǐng)了 wakelock 鎖,待機(jī)時(shí)沒(méi)有釋放掉锨咙,系統(tǒng)是不會(huì)進(jìn)入待機(jī)的语卤,直到所有應(yīng)用的 wakelock 鎖都釋放掉了,才會(huì)進(jìn)入待機(jī)酪刀。
2粹舵、應(yīng)用程序使用方法:
/**
*?獲取電源鎖,保持該服務(wù)在屏幕熄滅時(shí)仍然獲取CPU時(shí)骂倘,保持運(yùn)行
*/
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();
}
}
}
//?釋放設(shè)備電源鎖
private?void?releaseWakeLock()?{
if?(null?!=?wakeLock?&&?wakeLock.isHeld())?{
Log.i(TAG,?"call?releaseWakeLock");
wakeLock.release();
wakeLock?=?null;
}
}
WakeLock 類(lèi)型以及說(shuō)明:
PARTIAL_WAKE_LOCK:保持CPU 運(yùn)轉(zhuǎn)齐婴,屏幕和鍵盤(pán)燈有可能是關(guān)閉的。
SCREEN_DIM_WAKE_LOCK:保持CPU 運(yùn)轉(zhuǎn)稠茂,允許保持屏幕顯示但有可能是灰的柠偶,允許關(guān)閉鍵盤(pán)燈
SCREEN_BRIGHT_WAKE_LOCK:保持CPU 運(yùn)轉(zhuǎn),允許保持屏幕高亮顯示睬关,允許關(guān)閉鍵盤(pán)燈
FULL_WAKE_LOCK:保持CPU 運(yùn)轉(zhuǎn)诱担,保持屏幕高亮顯示,鍵盤(pán)燈也保持亮度
ACQUIRE_CAUSES_WAKEUP:強(qiáng)制使屏幕亮起电爹,這種鎖主要針對(duì)一些必須通知用戶(hù)的操作.
ON_AFTER_RELEASE:當(dāng)鎖被釋放時(shí)蔫仙,保持屏幕亮起一段時(shí)間
最后 AndroidManifest.xml 聲明權(quán)限:
應(yīng)用程序中如果要在待機(jī)前保存數(shù)據(jù)狀態(tài)的話(huà),要保證此過(guò)程中不會(huì)進(jìn)入待機(jī)丐箩∫“睿可以在 onResume() 或者 onStart() 中申請(qǐng) wakelock?鎖,即調(diào)用acquireWakeLock()方法屎勘。
在 onPause() 或者 onDistroy() 中處理應(yīng)用待機(jī)后再釋放掉 wakelock 鎖施籍,此時(shí)調(diào)用releaseWakeLock()方法
最后一點(diǎn)需要注意下:WakeLock的設(shè)置是 Activiy 級(jí)別的,不是針對(duì)整個(gè)Application應(yīng)用的概漱。所以application下有多個(gè)activity一定需要注意下丑慎!