WakeLock的介紹與使用

1.什麼是WakeLock

    WakeLock是一種機制,表示應用需要設備保持運行(stay on)。
    WakeLock默認是引用計數,如果WakeLock是引用計數的話,則調用了幾次acquire()方法,就需要調用對應次數的release()方法才能真正釋放掉WakeLock。
    如果WakeLock不是引用計數的話,則調用一次release()函數,就可以釋放前面調用多次acquire()獲取的WakeLock鎖。


2.如果使用WakeLock

    使用WakeLock之前,需要在AndroidManifest.xml中聲明android.permission.WAKE_LOCK權限。一般是通過使用PowerManager.newWakeLock(int,String)來獲取,並指定一個WakeLock類型:
  • FULL_WAKE_LOCK    保持屏幕全亮、鍵盤背光燈點亮和CPU運行。
  • SCREEN_BRIGHT_WAKE_LOCK   保持屏幕全亮和CPU運行。
  • SCREEN_DIM_WAKE_LOCK   保持屏幕開啓(但是讓它變暗)和CPU運行。
  • PARTIAL_WAKE_LOCK   保持CPU運行。
例如:
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);  
WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
 通過調用acquire()方法獲取Wake Lock對象,並可以指定一個超時值timeout,在該timeout內保持使用該WakeLock。
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);  
WakeLock wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");  
wakeLock.acquire(10000);//timeout = 10s
// do something that require the CPU is active    
wakeLock.release();  
當你完成了工作通過調用release()方法釋放WakeLock對象。
WakeLock的構造函數如下:
WakeLock(int flags, String tag, String packageName) {
            mFlags = flags;
            mTag = tag;
            mPackageName = packageName;
            mToken = new Binder();
            mTraceName = "WakeLock (" + mTag + ")";
        }
WakeLock帶timeout的acquire函數如下:
 public void acquire(long timeout) {
            synchronized (mToken) {
                acquireLocked();
                mHandler.postDelayed(mReleaser, timeout);
            }
        }
private void acquireLocked() {
            if (!mRefCounted || mCount++ == 0) {
                mHandler.removeCallbacks(mReleaser);
                Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, mTraceName, 0);
                try {
                    mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,
                            mHistoryTag);
                } catch (RemoteException e) {
                }
                mHeld = true;
            }
        }
WakeLock的釋放release函數如下:
public void release(int flags) {
            synchronized (mToken) {
                if (!mRefCounted || --mCount == 0) {
                    mHandler.removeCallbacks(mReleaser);
                    if (mHeld) {
                        Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, mTraceName, 0);
                        try {
                            mService.releaseWakeLock(mToken, flags);
                        } catch (RemoteException e) {
                        }
                        mHeld = false;
                    }
                }
                if (mCount < 0) {
                    throw new RuntimeException("WakeLock under-locked " + mTag);
                }
            }
        }

3.WakeLock的作用

    爲了延長電池的使用壽命,Android設備會在一段時間後使屏幕變暗,然後關閉屏幕顯示,最後停止CPU。WakeLock是一個電源管理系統服務功能,應用程序可以使用它來控制設備的電源狀態。
    WakeLock可以用來保持CPU運行,避免屏幕變暗和關閉,以及避免鍵盤背光燈熄滅。


4.WakeLock的使用場景

    屏幕Wake Lock通常用於在用戶觀看屏幕但是很少與屏幕進行交互期間(例如,播放視頻)防止屏幕變暗。
    CPU Wake Lock用於防止設備進入休眠狀態,直至執行了一個操作。當服務從意圖接收器內啓動時常常出現這種情況,因爲意圖接收器可能在設備休眠期間接收意圖。值得注意的是,在這種情況下,系統將在廣播接收器的整個onReceive處理程序中使用CPU Wake Lock。

5.WakeLock使用的注意事項

  • 在完成工作後,儘量快速釋放wake lock鎖,避免把電池耗盡。
  • 使用WakeLock時,儘量使用帶timeout的acquire方法,這樣即使應用發生了異常,也會自動釋放WakeLock。
  • 創建和使用Wake Lock會對應用程序造成的電池電量消耗產生顯著的影響。因此,最好只在 確實有必要時使用Wake Lock,並且使用它們的時間越少越好,只要有可 能就釋放它們。
  • 避免使用FULL_WAKE_LOCK,而應該使用WindowManger.LayoutParams.FLAG_KEEP_SCREEN_ON,因爲使用FLAG_KEEP_SCREEN_ON標誌,系統框架會自動處理相關的WakeLock釋放與重新獲得。
  • FULL_WAKE_LOCK、SCREEN_BRIGHT_WAKE_LOCK  、SCREEN_DIM_WAKE_LOCK 在按下Power電源鍵後,會被系統自動釋放,但是PARTIAL_WAKE_LOCK會保持CPU一直運行,直到partial wake lock已經被釋放了。


6.WindowManger.LayoutParams.FLAG_KEEP_SCREEN_ON標誌

    這是一個窗口標誌,只要窗口是可見的,則設備的屏幕會一直保持打開和常亮。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章