首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

Android ContentObserver 動態控制螢幕逾時任務實作

     編輯:關於C++

需求背景

在車載系統中,倒車或藍牙通話時需保持螢幕常亮,即取消螢幕逾時鎖定計時器。傳統做法是重置計時器,但更優雅的方式是動態啟用/停用該計時任務。

核心機制分析

經研究 PhoneWindowManager 原始碼,螢幕鎖定逾時最終由 mScreenLockTimeout 這個 Runnable 觸發:

ScreenLockTimeout mScreenLockTimeout = new ScreenLockTimeout();
class ScreenLockTimeout implements Runnable {
    Bundle options;
    @Override
    public void run() {
        synchronized (this) {
            if (mKeyguardDelegate != null) {
                mKeyguardDelegate.doKeyguardTimeout(options);
            }
            mLockScreenTimerActive = false;
            options = null;
        }
    }
    public void setLockOptions(Bundle options) { this.options = options; }
}

關鍵在於透過 Handler 的 postDelayed 與 removeCallbacks 動態控制此 Runnable 的執行。

ContentObserver 實作方案

利用 ContentObserver 監聽系統設定值變化,實現進程間通訊:寫入特定值即可動態新增/移除螢幕逾時任務。

private final class CalcScnTimeoutObserver extends ContentObserver {
    public CalcScnTimeoutObserver(Handler handler) { super(handler); }

    @Override
    public void onChange(boolean selfChange) {
        ContentResolver resolver = mContext.getContentResolver();
        int value = Settings.System.getIntForUser(resolver,
            Settings.System.SCREEN_TIMEOUT_CALC_INFO, 0, UserHandle.USER_CURRENT);

        if (value == 1) { // 取消任務
            synchronized (mScreenLockTimeout) {
                if (mLockScreenTimerActive) {
                    mHandler.removeCallbacks(mScreenLockTimeout);
                    mLockScreenTimerActive = false;
                }
            }
        } else if (value == 2) { // 新增/重置任務
            synchronized (mScreenLockTimeout) {
                if (mLockScreenTimerActive) {
                    mHandler.removeCallbacks(mScreenLockTimeout);
                }
                mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
                mLockScreenTimerActive = true;
            }
        }
    }

    void observe() {
        ContentResolver resolver = mContext.getContentResolver();
        resolver.registerContentObserver(
            Settings.System.getUriFor(Settings.System.SCREEN_TIMEOUT_CALC_INFO),
            false, this, UserHandle.USER_ALL);
    }
}

優點總結

  • 解耦:業務邏輯(倒車/通話)只需寫入設定值,無需直接操作系統服務。
  • 靈活:支援多進程、多使用者場景。
  • 簡潔:核心邏輯僅數十行,易於維護擴展。

Android 系統原始碼中蘊含大量實用設計模式,深入閱讀並靈活運用,能事半功倍。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved