前面也說了,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