前面也說了,ContentObserver可以來監控數據庫裡某一項數據的變化,當然也可以同時監控多個數據項的變化。筆者在項目中需要修改到屏幕超時的需求,比如在車載業務中,倒車事件發生的時候,是不需要屏幕超時變黑的,相當於這個計時timer要Reset一下,同樣在藍牙電話也要Reset一下,最好就是在這種特殊任務的時候,這個屏幕超時計時任務就不要跑起來,這樣是最好的,那怎麼實現呢?
筆者通過研究phonewindowsmanger.cpp中發現,最終都是驅動一個mScreenLockTimeout,它怎麼來的呢?見如下代碼:
<span style="font-size:18px;"> ScreenLockTimeout mScreenLockTimeout = new ScreenLockTimeout(); class ScreenLockTimeout implements Runnable { Bundle options; @Override public void run() { synchronized (this) { if (localLOGV) Log.v(TAG, "mScreenLockTimeout activating keyguard"); if (mKeyguardDelegate != null) { mKeyguardDelegate.doKeyguardTimeout(options); } mLockScreenTimerActive = false; options = null; } } public void setLockOptions(Bundle options) { this.options = options; } }</span>
Runnable 是重點啊!
返回欄目頁:http://www.bianceng.cn/Programming/cplus/
歸根結底還是驅動一個runnable。那怎麼控制呢?看到裡面的源碼,也有大量操作這個mScreenLockTimeout,可以動態的remove,再動態的啟動起來。筆者就想起了用contentobserver來做進程間通訊了,比如寫一個值代表取消這個任務,寫另外一個值就添加這個任務。筆者大概代碼如下:
private final class CalcScnTimeoutObserver extends ContentObserver { public CalcScnTimeoutObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange) { ContentResolver resolver = mContext.getContentResolver(); mCalcScnTimeoutValue = Settings.System.getIntForUser(resolver, Settings.System.SCREEN_TIMEOUT_CALC_INFO, 0, UserHandle.USER_CURRENT); Slog.d(TAG,"##CalcScnTimeoutObserver: " + mCalcScnTimeoutValue); if(1 == mCalcScnTimeoutValue){ synchronized (mScreenLockTimeout) { if (mLockScreenTimerActive) { // reset the timer mHandler.removeCallbacks(mScreenLockTimeout); //mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); mLockScreenTimerActive = false; } } } else if(2 == mCalcScnTimeoutValue){ synchronized (mScreenLockTimeout) { if (mLockScreenTimerActive) { // reset the timer mHandler.removeCallbacks(mScreenLockTimeout); mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); } else { mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); mLockScreenTimerActive = true; } } }else { Slog.e(TAG,"default novalid value "); } } void observe() { // Observe all users' changes ContentResolver resolver = mContext.getContentResolver(); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.SCREEN_TIMEOUT_CALC_INFO), false, this, UserHandle.USER_ALL); } }
通過這樣已處理,就能達到動態控制這個任務的作用,還是非常簡單實用的。源碼裡還是有很多精華代碼及處理方法,關鍵是我們要去熟悉、了解、掌握、靈活運用!android之大,駕馭了就是美,駕馭不了就是魔!繼續努力!
作者:csdn博客 sundesheng125