前面也说了。ContentObserver能够来监控数据库里某一项数据的变化,当然也能够同一时候监控多个数据项的变化。
笔者在项目中须要改动到屏幕超时的需求,比方在车载业务中,倒车事件发生的时候,是不须要屏幕超时变黑的,相当于这个计时timer要Reset一下,相同在蓝牙电话也要Reset一下,最好就是在这样的特殊任务的时候。这个屏幕超时计时任务就不要跑起来,这样是最好的。那怎么实现呢?
笔者通过研究phonewindowsmanger.cpp中发现,终于都是驱动一个mScreenLockTimeout。它怎么来的呢?见例如以下代码:
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;
}
}
Runnable 是重点啊。
归根结底还是驱动一个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); } }通过这样已处理,就能达到动态控制这个任务的作用,还是非常easy有用的。源代码里还是有非常多精华代码及处理方法。关键是我们要去熟悉、了解、掌握、灵活运用!android之大,驾驭了就是美。驾驭不了就是魔!继续努力!