Android7.0 PowerManagerService(2) WakeLock的使用及流程
作為移動(dòng)終端,電量是一種稀缺資源,需要盡可能的節(jié)省。于是,Android系統(tǒng)在空閑時(shí),會(huì)主動(dòng)進(jìn)入到休眠狀態(tài)。?
我們知道整個(gè)Android系統(tǒng)中運(yùn)行著很多個(gè)進(jìn)程,因此必須有一種機(jī)制能夠知道每個(gè)進(jìn)程是否正在進(jìn)行重要的工作,只有這樣Android系統(tǒng)才能對(duì)整個(gè)終端當(dāng)前的狀態(tài)做出判斷。
顯然我們不能啟動(dòng)一個(gè)進(jìn)程,去主動(dòng)監(jiān)管其它所有進(jìn)程的工作狀態(tài),這樣CPU開銷太大,反而加劇了電量的消耗。為此Android引入了基于WakeLock的電量管理機(jī)制,而PMS就是專門負(fù)責(zé)管理WakeLock的進(jìn)程。
個(gè)人覺得WakeLock機(jī)制的思想,有點(diǎn)類似于早期通信領(lǐng)域局域網(wǎng)中的令牌環(huán)機(jī)制。當(dāng)局域網(wǎng)中有設(shè)備需要發(fā)送數(shù)據(jù)時(shí),需要申請(qǐng)令牌(Token),申請(qǐng)到令牌才能發(fā)送數(shù)據(jù);設(shè)備發(fā)送完數(shù)據(jù)后,再釋放掉令牌。
與此相似,Android設(shè)備中運(yùn)行的進(jìn)程需要使用電量資源時(shí),也需要向PMS申請(qǐng)一個(gè)WakeLock;當(dāng)工作完成后,就釋放掉申請(qǐng)的WakeLock。PMS通過判斷當(dāng)前是否還有進(jìn)程持有WakeLock,就能得出系統(tǒng)是否空閑的結(jié)論。
從這里也可以看出,當(dāng)我們寫一個(gè)永不停止工作的線程,但不申請(qǐng)WakeLock時(shí),系統(tǒng)仍然可以休眠。在休眠時(shí),CPU不會(huì)再耗費(fèi)資源去調(diào)度該線程,于是“永不停止工作”被打上了引號(hào)。
接下來,我們就來看看PMS中的WakeLock。
一、創(chuàng)建WakeLock?
我們以RIL.java為例,看看一般情況下,PMS以外的其它進(jìn)程如何使用WakeLock。?
在RIL.java的構(gòu)造函數(shù)中:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
從上面的代碼,可以看出調(diào)用PowerManager的newWakeLock函數(shù),可以創(chuàng)建出WakeLock。
我們看看newWakeLock函數(shù)定義:
public WakeLock newWakeLock(int levelAndFlags, String tag) {//檢查參數(shù)有效性,即levelAndFlags必須對(duì)應(yīng)于PowerManager中定義的WakeLock級(jí)別和flag,tag不能為空validateWakeLockParameters(levelAndFlags, tag);//此WakeLock為PowerManager定義的內(nèi)部類return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName()); }- 1
- 2
- 3
- 4
- 5
- 6
- 7
1、WakeLock Level?
newWakeLock中的第一個(gè)參數(shù)對(duì)應(yīng)于WakeLock的級(jí)別和標(biāo)志位構(gòu)成的位圖。?
目前,在PowerManger中一共為WakeLock定義了7種level。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
從上面的代碼注釋可以看出,WakeLock主要用于控制CPU、屏幕和鍵盤三大部分(當(dāng)然,現(xiàn)在的Anroid中基本沒有鍵盤了)。?
對(duì)于PARTIAL_WAKE_LOCK、SCREEN_DIM_WAKE_LOCK、SCREEN_BRIGHT_WAKE_LOCK和FULL_WAKE_LOCK而言,不考慮Power鍵的話,隨著等級(jí)的提高,權(quán)限也相應(yīng)增大,即持有高等級(jí)的鎖,能夠激活的部分越多;如果考慮Power鍵的話,PARTIAL_WAKE_LOCK可以保證CPU不休眠,反而是權(quán)限最大的。
PROXIMITY_SCREEN_OFF_WAKE_LOCK、DOZE_WAKE_LOCK和DRAW_WAKE_LOCK都是和具體場(chǎng)景相關(guān)的鎖。
2、WakeLock Flag?
PowerManager定義的WakeLock Flag很多,無法一一列舉,就看一下比較常用的:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
總結(jié)一下上面的內(nèi)容,如下所示:?
?
WakeLock Flag一般與WakeLock Level組合使用,使用的時(shí)候參照一下注釋即可。
3、WakeLock的構(gòu)造函數(shù)?
最后,我們來看看WakeLock的構(gòu)造函數(shù):
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
WakeLock的構(gòu)造函數(shù)中需要注意的地方是,創(chuàng)建了一個(gè)Binder對(duì)象。?
回憶一下RIL.java中創(chuàng)建WakeLock的過程,我們就知道這個(gè)Binder對(duì)象應(yīng)該是創(chuàng)建在RIL.java所在的Phone進(jìn)程中。
二、Acquire WakeLock?
從上面的分析,我們知道一個(gè)進(jìn)程創(chuàng)建的WakeLock,實(shí)際上表明了該進(jìn)程執(zhí)行某個(gè)工作時(shí)對(duì)電量的需求,例如聲明該工作需要保持屏幕處于點(diǎn)亮狀態(tài),或該工作需要CPU處于喚醒態(tài)等。?
因此,進(jìn)程創(chuàng)建了WakeLock后,需要將WakeLock發(fā)送到PMS中,讓PMS明白該進(jìn)程的需求。?
這種將WakeLock通知到PMS的過程,就被稱為acquire WakeLock。
同樣,我們還是以RIL.java中的使用過程舉例:
private void send(RILRequest rr) {Message msg;if (mSocket == null) {rr.onError(RADIO_NOT_AVAILABLE, null);rr.release();return;}msg = mSender.obtainMessage(EVENT_SEND, rr);//重點(diǎn)在這里acquireWakeLock(rr, FOR_WAKELOCK);msg.sendToTarget(); }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
當(dāng)AP側(cè)向modem發(fā)送請(qǐng)求時(shí),將要調(diào)用RIL.java的send函數(shù)。send函數(shù)將會(huì)發(fā)送消息給RILSender,后者利用socket將消息發(fā)送給rild進(jìn)程。?
從上面的代碼可以看出,在發(fā)送消息給RILSender之前,調(diào)用了acquireWakeLock函數(shù):
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
我們跟進(jìn)一下PowerManager中WakeLock的acquire函數(shù):
public void acquire() {synchronized (mToken) {acquireLocked();} }private void acquireLocked() {//前面已經(jīng)提過,RIL.java中已經(jīng)將mRefCounted置為false//如果不將mRefCounted置為false,意味著acquire和release必須一一對(duì)應(yīng)//那么每個(gè)WakeLock只能acquire一次if (!mRefCounted || mCount++ == 0) {........try {mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,mHistoryTag);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}mHeld = true;} }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
容易看出實(shí)際的工作流程將通過Binder通信進(jìn)入到PMS中:
public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,WorkSource ws, String historyTag) {//參數(shù)和權(quán)限檢查............final int uid = Binder.getCallingUid();final int pid = Binder.getCallingPid();final long ident = Binder.clearCallingIdentity();try {acquireWakeLockInternal(lock, flags, tag, packageName, ws, historyTag, uid, pid);} finally {Binder.restoreCallingIdentity(ident);} }private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,WorkSource ws, String historyTag, int uid, int pid) {synchronized (mLock) {...........//PMS中也定義了WakeLock內(nèi)部類WakeLock wakeLock;//PMS中維持了一個(gè)ArrayList,記錄當(dāng)前已申請(qǐng)的WakeLock//findWakeLockIndexLocked查找ArrayList,判斷參數(shù)對(duì)應(yīng)的WakeLock,是否在之前被申請(qǐng)過int index = findWakeLockIndexLocked(lock);boolean notifyAcquire;if (index >= 0) {//如果index大于0,說明此時(shí)Acquire的是一個(gè)舊的WakeLock//例如RIL會(huì)多次調(diào)用send函數(shù),于是除第一次外,都會(huì)進(jìn)入這個(gè)分支wakeLock = mWakeLocks.get(index);//這是判斷WakeLock對(duì)應(yīng)的成員變量是否發(fā)生改變if (!wakeLock.hasSameProperties(flags, tag, ws, uid, pid)) {// Update existing wake lock. This shouldn't happen but is harmless.notifyWakeLockChangingLocked(wakeLock, flags, tag, packageName,uid, pid, ws, historyTag);//若wakelock屬性發(fā)生了變化,更新該屬性wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid);}notifyAcquire = false;} else {//創(chuàng)建一個(gè)新的WakeLock,例如RIL第一次調(diào)用send就會(huì)進(jìn)入該分支wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid);try {//1、監(jiān)控申請(qǐng)WakeLock的進(jìn)程是否死亡lock.linkToDeath(wakeLock, 0);} catch (RemoteException ex) {throw new IllegalArgumentException("Wake lock is already dead.");}//添加到wakelock列表mWakeLocks.add(wakeLock);//2、特殊處理PARTIAL_WAKE_LOCK//實(shí)際上,根據(jù)Doze模式的白名單更新wakelock的disabled變量setWakeLockDisabledStateLocked(wakeLock);notifyAcquire = true;}//3、處理WakeLock對(duì)應(yīng)的Flag//實(shí)際上判斷WakeLock是否有ACQUIRE_CAUSES_WAKEUP,在必要時(shí)喚醒屏幕applyWakeLockFlagsOnAcquireLocked(wakeLock, uid);mDirty |= DIRTY_WAKE_LOCKS;//更新電源狀態(tài),以后單獨(dú)分析updatePowerStateLocked();if (notifyAcquire) {// This needs to be done last so we are sure we have acquired the// kernel wake lock. Otherwise we have a race where the system may// go to sleep between the time we start the accounting in battery// stats and when we actually get around to telling the kernel to// stay awake.//通知wakeLock發(fā)生變化 //電量統(tǒng)計(jì)服務(wù)做相關(guān)統(tǒng)計(jì)notifyWakeLockAcquiredLocked(wakeLock);}} }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
如上代碼中標(biāo)注的注釋,acquireWakeLockInternal中有幾處比較重要的地方,我們一起來分析一下。
1、監(jiān)聽客戶端進(jìn)程死亡?
上面的代碼中,第一次創(chuàng)建WakeLock后,調(diào)用了:
- 1
- 2
- 3
我們將acquire WakeLock的進(jìn)程定義為PMS的客戶端進(jìn)程,那么上面代碼的lock,就是客戶端進(jìn)程中創(chuàng)建的Binder對(duì)象的代理。對(duì)于RIL而言,就是存在于Phone進(jìn)程中的Binder的代理。?
PMS調(diào)用Binder代理的linkToDeath,實(shí)際上使得PMS成為了對(duì)應(yīng)進(jìn)程Binder的客戶端。于是,當(dāng)對(duì)應(yīng)進(jìn)程死亡后,將通知PMS。?
linkToDeath傳入的必須是繼承IBinder.DeathRecipient的對(duì)象,作為進(jìn)程死亡的”訃告”接收者。
我們看看PMS中WakeLock與此相關(guān)的定義:
private final class WakeLock implements IBinder.DeathRecipient {...........@Overridepublic void binderDied() {//發(fā)現(xiàn)客戶端進(jìn)程死亡后,調(diào)用PMS的handleWakeLockDeath進(jìn)行處理,傳入的參數(shù)為WakeLock自己PowerManagerService.this.handleWakeLockDeath(this);}....... }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
我們看看PMS的handleWakeLockDeath函數(shù):
private void handleWakeLockDeath(WakeLock wakeLock) {synchronized (mLock) {..........int index = mWakeLocks.indexOf(wakeLock);if (index < 0) {return;}removeWakeLockLocked(wakeLock, index);} }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
跟進(jìn)removeWakeLockLocked函數(shù):
private void removeWakeLockLocked(WakeLock wakeLock, int index) {mWakeLocks.remove(index);//通知到BatteryStatsServicenotifyWakeLockReleasedLocked(wakeLock);//處理WakeLock對(duì)應(yīng)的flag,與后文applyWakeLockFlagsOnAcquireLocked一起分析//實(shí)際上是判斷是否需要立即息屏applyWakeLockFlagsOnReleaseLocked(wakeLock);mDirty |= DIRTY_WAKE_LOCKS;//鎖移除后,還是利用updatePowerStateLocked更新電源狀態(tài)updatePowerStateLocked(); }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
2、特殊處理PARTIAL_WAKE_LOCK?
PMS處理第一次創(chuàng)建的WakeLock時(shí),還會(huì)調(diào)用setWakeLockDisabledStateLocked函數(shù)進(jìn)行處理:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
上面代碼大致的含義就是:?
在Android Doze模式下,當(dāng)終端處于device Idle Mode時(shí),?
對(duì)于一個(gè)非系統(tǒng)應(yīng)用而言,如果該應(yīng)用不在系統(tǒng)定義的白名單中,?
并且該應(yīng)用所在進(jìn)程的類型表明,該進(jìn)程對(duì)事件處理的時(shí)效性要求不高,?
那么即使該應(yīng)用申請(qǐng)了PARTIAL_WAKE_LOCK,也不能阻止系統(tǒng)進(jìn)入休眠狀態(tài)。
有些設(shè)備商,為了優(yōu)化系統(tǒng)的功耗,就修改了這個(gè)地方。?
例如,有些系統(tǒng)應(yīng)用其實(shí)也很耗電,因此可以去掉該函數(shù)中對(duì)非系統(tǒng)應(yīng)用的限制,對(duì)系統(tǒng)應(yīng)用也進(jìn)行管控。
3、處理WakeLock對(duì)應(yīng)的Flag?
前面的代碼已經(jīng)提到,當(dāng)acquire WakeLock時(shí),將調(diào)用applyWakeLockFlagsOnAcquireLocked處理WakeLock對(duì)應(yīng)的flag;?
當(dāng)由于進(jìn)程死亡,釋放WakeLock時(shí),會(huì)調(diào)用applyWakeLockFlagsOnReleaseLocked處理WakeLock對(duì)應(yīng)的flag。?
從函數(shù)命名來看,這兩個(gè)函數(shù)應(yīng)該有相似的地方。
3.1 applyWakeLockFlagsOnAcquireLocked?
我們先看看applyWakeLockFlagsOnAcquireLocked:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
3.1.1 setWakefulnessLocked?
我們看看喚醒屏幕相關(guān)的操作:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
從上面的代碼來看,應(yīng)該是PhoneWindowManager完成亮屏前的初始化工作,然后回調(diào)到PowerManager的wakeUp函數(shù)。?
整個(gè)過程還是比較復(fù)雜的,需要單獨(dú)進(jìn)行分析,此處不做進(jìn)一步說明。
3.2 applyWakeLockFlagsOnReleaseLocked?
現(xiàn)在我們?cè)倏纯碼pplyWakeLockFlagsOnReleaseLocked函數(shù):
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
可以看出applyWakeLockFlagsOnAcquireLocked和applyWakeLockFlagsOnReleaseLocked最后均會(huì)調(diào)用userActivityNoUpdateLocked函數(shù),只是參數(shù)不同。
3.3 userActivityNoUpdateLocked?
我們一起來看一下userActivityNoUpdateLocked:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
從以上代碼來看,acquire WakeLock將申請(qǐng)信息遞交給PMS統(tǒng)一進(jìn)行處理。?
PMS根據(jù)WakeLock的level和flag,完成修改一些變量、通知BatteryStatsService等工作后,?
最終還是依賴于updatePowerStateLocked函數(shù)來進(jìn)行實(shí)際的電源狀態(tài)更新操作。
PMS類中有很多***NoUpdateLocked()方法,這些方法都有一些共性,就是僅更新狀態(tài),不負(fù)責(zé)具體的執(zhí)行。因?yàn)镻MS中具體的執(zhí)行邏輯都是在updatePowerStateLocked方法中。
上述acquire WakeLock主要的工作大致可以總結(jié)為下圖:?
三、釋放WakeLock?
當(dāng)進(jìn)程完成工作后,需要釋放之前申請(qǐng)的WakeLock。我們同樣以RIL.java中的操作為例:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
我們跟進(jìn)decrementWakeLock函數(shù):
private void decrementWakeLock(RILRequest rr) {synchronized(rr) {switch(rr.mWakeLockType) {case FOR_WAKELOCK:synchronized (mWakeLock) {//前面已經(jīng)提到過,RIL.java多個(gè)請(qǐng)求復(fù)用同一個(gè)WakeLock//并且利用mWakeLockCount記錄復(fù)用的次數(shù)//這么設(shè)計(jì)的目的是:RIL發(fā)送請(qǐng)求的數(shù)量非常多,復(fù)用WakeLock可以避免多次構(gòu)造釋放//同時(shí)減少與PMS之間Binder通信的次數(shù)if (mWakeLockCount > 1) {mWakeLockCount--;} else {mWakeLockCount = 0;//所有請(qǐng)求均得到了處理,調(diào)用PowerManager中WakeLock的release函數(shù)mWakeLock.release();}}break;........}}........ }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
現(xiàn)在我們跟進(jìn)PowerManager中WakeLock定義的release函數(shù):
/** * Releases the wake lock with flags to modify the release behavior. * * This method releases your claim to the CPU or screen being on. * The screen may turn off shortly after you release the wake lock, or it may * not if there are other wake locks still held. * */ public void release(int flags) {synchronized (mToken) {if (!mRefCounted || --mCount == 0) {mHandler.removeCallbacks(mReleaser);if (mHeld) {.......try {//還是會(huì)調(diào)用到PMS中的函數(shù)mService.releaseWakeLock(mToken, flags);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}mHeld = false;}}....} }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
最后一起來看看PMS中釋放WakeLock的函數(shù):
public void releaseWakeLock(IBinder lock, int flags) {//參數(shù)和權(quán)限檢查.............final long ident = Binder.clearCallingIdentity();try {releaseWakeLockInternal(lock, flags);} finally {Binder.restoreCallingIdentity(ident);} }private void releaseWakeLockInternal(IBinder lock, int flags) {synchronized (mLock) {//根據(jù)Binder代理,從存儲(chǔ)的ArrayList中找到對(duì)應(yīng)WakeLock的序號(hào)int index = findWakeLockIndexLocked(lock);...........WakeLock wakeLock = mWakeLocks.get(index);...........//RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY,表示當(dāng)sensor判斷終端離物體較遠(yuǎn)時(shí),//才真正釋放PROXIMITY_SCREEN_OFF_WAKE_LOCK等級(jí)的WakeLockif ((flags & PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY) != 0) {mRequestWaitForNegativeProximity = true;}//PMS不再關(guān)注客戶端進(jìn)程是否死亡wakeLock.mLock.unlinkToDeath(wakeLock, 0);removeWakeLockLocked(wakeLock, index);} }private void removeWakeLockLocked(WakeLock wakeLock, int index) {mWakeLocks.remove(index);//通知BatteryStatsServicenotifyWakeLockReleasedLocked(wakeLock);//之前分析過,會(huì)做一些記錄信息等applyWakeLockFlagsOnReleaseLocked(wakeLock);mDirty |= DIRTY_WAKE_LOCKS;//依然靠updatePowerStateLocked函數(shù)更新終端的電源狀態(tài)updatePowerStateLocked(); }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
整個(gè)release的過程大致可以總結(jié)為下圖:?
四、總結(jié)?
通過前面的分析,我們知道了向PMS申請(qǐng)電量的基本用法類似于:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
當(dāng)申請(qǐng)發(fā)送到PMS后,PMS將針對(duì)WakeLock的level和flag信息進(jìn)行一些處理。?
無論是acquire還是release WakeLock,PMS最終將利用updatePowerStateLocked函數(shù)對(duì)終端的電源狀態(tài)進(jìn)行調(diào)整。?
我們將單獨(dú)分析一下PMS核心的updatePowerStateLocked函數(shù)。
原文地址:http://blog.csdn.net/gaugamela/article/details/52813400
總結(jié)
以上是生活随笔為你收集整理的Android7.0 PowerManagerService(2) WakeLock的使用及流程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android7.0 PowerMana
- 下一篇: android sina oauth2.