第四章:PowerManagerService

簡(jiǎn)述

PowerManagerServcie是android系統(tǒng)電源管理的核心服務(wù),它在Framework層建立起一個(gè)策略控制方案,向下決策HAL層以及kernel層來(lái)控制設(shè)備待機(jī)狀態(tài),主要功能是控制系統(tǒng)待機(jī)狀態(tài),屏幕顯示,亮度調(diào)節(jié),光線/距離傳感器的控制等。

除了與應(yīng)用程序交互之外,還要與系統(tǒng)中其它模塊配合,在提供良好的能源管理同時(shí)提供友好的用戶體驗(yàn)。比如聽(tīng)音樂(lè)時(shí)持續(xù)保持系統(tǒng)喚醒,應(yīng)用通知來(lái)臨喚醒手機(jī)屏幕等場(chǎng)景

分析一個(gè)服務(wù),首先要從它對(duì)應(yīng)用層提供的api PowerManager入手,觀察提供了哪些接口調(diào)用;

  • Wakeup():強(qiáng)制系統(tǒng)從睡眠狀態(tài)喚醒,此接口對(duì)應(yīng)用是不開(kāi)放的,應(yīng)用想喚醒系統(tǒng)必須通過(guò)設(shè)置亮屏標(biāo)志(后面即將講到);
  • gotoSleep():強(qiáng)制系統(tǒng)進(jìn)入到睡眠狀態(tài),此接口也是應(yīng)用不開(kāi)放。
  • userActivity():向PowerManagerService報(bào)告影響系統(tǒng)休眠的用戶活動(dòng),重計(jì)算滅屏?xí)r間,背光亮度等,例如觸屏,劃屏,power鍵等用戶活動(dòng);
  • Wakelock:wakelock是PowerManager的一個(gè)內(nèi)部類,提供了相關(guān)的接口來(lái)操作wakelock鎖,比如newWakeLock()方法來(lái)創(chuàng)建wakelock鎖,acquire()和release()方法來(lái)申請(qǐng)和釋放鎖。下面例子有介紹!
  • isDeviceIdleMode():返回設(shè)備當(dāng)前的狀態(tài),如果處于Idle狀態(tài),則返回true,Idle狀態(tài)是在手機(jī)長(zhǎng)時(shí)間沒(méi)有被使用以及沒(méi)有運(yùn)動(dòng)的情況下,手機(jī)進(jìn)入到一種Doze低功耗的模式下,這種狀態(tài)下手機(jī)可能會(huì)關(guān)掉網(wǎng)絡(luò)數(shù)據(jù)訪問(wèn),可以通過(guò)監(jiān)視DEVICE_IDLE_MODE_CHANGED這個(gè)廣播信息,來(lái)監(jiān)控手機(jī)狀態(tài)的改變

系統(tǒng)層級(jí)圖

image.png

電源管理架構(gòu)
主要分為四個(gè)層次:

  • 應(yīng)用接口層:PowerManager.java中開(kāi)放給應(yīng)用一系列接口,應(yīng)用可以調(diào)用PM的接口申請(qǐng)wakelock,喚醒系統(tǒng),使系統(tǒng)進(jìn)入睡眠等操作;
  • Framework層:PowerManagerService.java計(jì)算系統(tǒng)中和Power相關(guān)的計(jì)算,是整個(gè)電源管理的決策系;
  • HAL層:該層只有一個(gè)power.c文件,該文件通過(guò)上層傳下來(lái)的參數(shù),向/sys/power/wake_lock或者/sys/power/wake_unlock文件節(jié)點(diǎn)寫數(shù)據(jù)來(lái)與kernel進(jìn)行通信,主要功能是申請(qǐng)/釋放鎖,維持屏幕亮滅。
  • Kernel層:內(nèi)核層實(shí)現(xiàn)電源管理的方案主要包含三個(gè)部分:
    Kernel/power/:實(shí)現(xiàn)了系統(tǒng)電源管理框架機(jī)制。
    Arch/arm(ormips or powerpc)/mach-XXX/pm.c:實(shí)現(xiàn)對(duì)特定板的處理器電源管理。
    drivers/power:是設(shè)備電源管理的基礎(chǔ)框架,為驅(qū)動(dòng)提供了電源管理接口。

一、 初始化

跟其他系統(tǒng)服務(wù)一樣,PowerManagerService也是繼承于SystemService并通過(guò)SystemServer啟動(dòng)。
SystemServer啟動(dòng)PowerManagerService服務(wù)
frameworks/base/services/java/com/android/server/SystemServer.java

private void startBootstrapServices() {
  ......
  mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
  ......
}

PowerManagerService構(gòu)造
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

public final class PowerManagerService extends SystemService
        implements Watchdog.Monitor {
    public PowerManagerService(Context context) {
        super(context);
        mContext = context;
//創(chuàng)建消息處理線程,并啟動(dòng)
        mHandlerThread = new ServiceThread(TAG,
                Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
        mHandlerThread.start();
//創(chuàng)建Hanlder對(duì)象處理消息
        mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
        mConstants = new Constants(mHandler);
        mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
        mBatterySaverPolicy = new BatterySaverPolicy(mHandler);

        synchronized (mLock) {
            //創(chuàng)建"PowerManagerService.WakeLocks"的SuspendBlocker
            mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
           // 創(chuàng)建"PowerManagerService.Display"的SuspendBlocker
            mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
           // 請(qǐng)求DisplaySuspendBlocker,禁止系統(tǒng)進(jìn)入休眠
            mDisplaySuspendBlocker.acquire();
            mHoldingDisplaySuspendBlocker = true;
            mHalAutoSuspendModeEnabled = false;
            mHalInteractiveModeEnabled = true;
           // 設(shè)置mWakefulness為喚醒狀態(tài)
            mWakefulness = WAKEFULNESS_AWAKE;

            sQuiescent = SystemProperties.get(SYSTEM_PROPERTY_QUIESCENT, "0").equals("1");
           // 進(jìn)入到native層初始化
            nativeInit();
            nativeSetAutoSuspend(false);
            nativeSetInteractive(true);
            nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
        }
    }
    ......
}

PowerManagerService構(gòu)造函數(shù)中首先創(chuàng)建了處理消息的進(jìn)程及對(duì)應(yīng)的handler對(duì)象以進(jìn)行消息處理,然后創(chuàng)建SuspendBlocker對(duì)象,用于WakeLocks與Display,并設(shè)置mWakefulness的初始狀態(tài)為WAKEFULNESS_AWAKE,最后進(jìn)入到native層初始化。下面先看一下關(guān)于mWakefulness的定義。
frameworks/base/core/java/android/os/PowerManagerInternal.java

/**
 * 設(shè)備處于休眠狀態(tài),只能被wakeUp()喚醒.
 */
public static final int WAKEFULNESS_ASLEEP = 0;

/**
 * 設(shè)備處于正常工作(fully awake)狀態(tài).
 */
public static final int WAKEFULNESS_AWAKE = 1;

/**
 * 設(shè)備處于播放屏保狀態(tài).
 */
public static final int WAKEFULNESS_DREAMING = 2;

/**
 * 設(shè)備處于doze狀態(tài),只有低耗電的屏保可以運(yùn)行,其他應(yīng)用被掛起.
 */
public static final int WAKEFULNESS_DOZING = 3;

繼續(xù)回到PowerManagerService構(gòu)造函數(shù)的native初始化中,首先來(lái)看nativeInit的實(shí)現(xiàn)。
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp

static void nativeInit(JNIEnv* env, jobject obj) {
   // 創(chuàng)建一個(gè)全局對(duì)象,引用PMS
   gPowerManagerServiceObj = env->NewGlobalRef(obj);
   // 利用hw_get_module加載power模塊
   status_t err = hw_get_module(POWER_HARDWARE_MODULE_ID,
           (hw_module_t const**)&gPowerModule);
   if (!err) {
       gPowerModule->init(gPowerModule);
   } else {
       ALOGE("Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err));
   }
}

nativeInit的主要任務(wù)時(shí)裝載power模塊,該模塊由廠商實(shí)現(xiàn),以高通為例,如下。
device/qcom/common/power/power.c

tatic struct hw_module_methods_t power_module_methods = {
    .open = NULL,
};

struct power_module HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = POWER_MODULE_API_VERSION_0_2,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = POWER_HARDWARE_MODULE_ID,
        .name = "QCOM Power HAL",
        .author = "Qualcomm",
        .methods = &power_module_methods,
    },

    .init = power_init,
    .powerHint = power_hint,
    .setInteractive = set_interactive,
};

power_module中實(shí)現(xiàn)了init,powerHint,setInteractive,nativeInit最終調(diào)用到HAL power模塊的power_init具體實(shí)現(xiàn)中。接著看native初始化nativeSetAutoSuspend的實(shí)現(xiàn)。
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp

static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
    if (enable) {
        ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_enable() while turning screen off");
        autosuspend_enable();
    } else {
        ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_disable() while turning screen on");
        autosuspend_disable();
    }
}
static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
    if (gPowerModule) {
        if (enable) {
            ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on");
            gPowerModule->setInteractive(gPowerModule, true);
        } else {
            ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(false) while turning screen off");
            gPowerModule->setInteractive(gPowerModule, false);
        }
    }
}

static void nativeSetFeature(JNIEnv *env, jclass clazz, jint featureId, jint data) {
    int data_param = data;

    if (gPowerModule && gPowerModule->setFeature) {
        gPowerModule->setFeature(gPowerModule, (feature_t)featureId, data_param);
    }
}

system/core/libsuspend/autosuspend.c

int autosuspend_disable(void)
{
    int ret;

    ret = autosuspend_init();
    if (ret) {
        return ret;
    }

    ALOGV("autosuspend_disable\n");

    if (!autosuspend_enabled) {
        return 0;
    }

    ret = autosuspend_ops->disable();
    if (ret) {
        return ret;
    }

    autosuspend_enabled = false;
    return 0;
}

同nativeInit一樣,最終都是調(diào)用到HAL power模塊的具體實(shí)現(xiàn)中。

二、 啟動(dòng)

下面繼續(xù)看PowerManagerService在系統(tǒng)啟動(dòng)過(guò)程中回調(diào)onStart(),onBootPhase(),systemReady()的實(shí)現(xiàn)。
啟動(dòng)服務(wù)SystemServiceManager.onStart
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

public void onStart() {
    publishBinderService(Context.POWER_SERVICE, new BinderService());
    publishLocalService(PowerManagerInternal.class, new LocalService());

    Watchdog.getInstance().addMonitor(this);
    Watchdog.getInstance().addThread(mHandler);
}

private final class BinderService extends IPowerManager.Stub {
    ......
}

private final class LocalService extends PowerManagerInternal {
    ......
}

onStart()中發(fā)布了BinderServiceLocalService分別供其他進(jìn)程,進(jìn)程內(nèi)其他服務(wù)調(diào)用,并將PowerManagerService加入到Watchdog監(jiān)控中。

啟動(dòng)服務(wù)SystemServiceManager.onBootPhase

public void onBootPhase(int phase) {
    synchronized (mLock) {
        if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
            ......
        } else if (phase == PHASE_BOOT_COMPLETED) {
            final long now = SystemClock.uptimeMillis();
            // 設(shè)置mBootCompleted狀態(tài)
            mBootCompleted = true;
            mDirty |= DIRTY_BOOT_COMPLETED;
            // 更新userActivity及PowerState,后面分析
            userActivityNoUpdateLocked(
                    now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
            updatePowerStateLocked();
            // 執(zhí)行mBootCompletedRunnables中的runnable方法
            if (!ArrayUtils.isEmpty(mBootCompletedRunnables)) {
                Slog.d(TAG, "Posting " + mBootCompletedRunnables.length + " delayed runnables");
                for (Runnable r : mBootCompletedRunnables) {
                    BackgroundThread.getHandler().post(r);
                }
            }
            mBootCompletedRunnables = null;
        }
    }
}

onBootPhase()中主要設(shè)置mBootCompleted狀態(tài),更新PowerState狀態(tài),并執(zhí)行mBootCompletedRunnables中的runnables方法(低電量模式會(huì)設(shè)置)。
啟動(dòng)服務(wù)SystemServiceManager.systemReady

public void systemReady(IAppOpsService appOps) {
    synchronized (mLock) {
        mSystemReady = true;
        // 獲取AppOpsService
        mAppOps = appOps;
        // 獲取DreamManager 屏保
        mDreamManager = getLocalService(DreamManagerInternal.class);
        // 獲取DisplayManagerService  屏幕顯示
        mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
      //窗口策略
        mPolicy = getLocalService(WindowManagerPolicy.class);
        // 獲取mBatteryService 電池電量
        mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);

        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        // 獲取屏幕默認(rèn),最大,最小亮度
        mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
        mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
        mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
        // 獲取SensorManager
        SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());

        mBatteryStats = BatteryStatsService.getService();
        // 創(chuàng)建Notifier對(duì)象,用于廣播power state的變化
        mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
                mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
                mPolicy);
        // 無(wú)線充電檢測(cè)
        mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
                createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
                mHandler);
        // 監(jiān)聽(tīng)設(shè)置的變化
        mSettingsObserver = new SettingsObserver(mHandler);

        mLightsManager = getLocalService(LightsManager.class);
        mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);

        // Initialize display power management.
        mDisplayManagerInternal.initPowerManagement(
                mDisplayPowerCallbacks, mHandler, sensorManager);

        // Register for settings changes.
        final ContentResolver resolver = mContext.getContentResolver();
        resolver.registerContentObserver(Settings.Secure.getUriFor(
                Settings.Secure.SCREENSAVER_ENABLED),
        ......
        IVrManager vrManager =
                (IVrManager) getBinderService(VrManagerService.VR_MANAGER_BINDER_SERVICE);
        try {
            vrManager.registerListener(mVrStateCallbacks);
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to register VR mode state listener: " + e);
        }
        // 讀取配置
        readConfigurationLocked();
        updateSettingsLocked();
        mDirty |= DIRTY_BATTERY_STATE;
        updatePowerStateLocked();
    }

    // Register for broadcasts from other components of the system.
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_BATTERY_CHANGED);
    filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
    mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);

    filter = new IntentFilter();
    filter.addAction(Intent.ACTION_DREAMING_STARTED);
    filter.addAction(Intent.ACTION_DREAMING_STOPPED);
    mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);

    filter = new IntentFilter();
    filter.addAction(Intent.ACTION_USER_SWITCHED);
    mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);

    filter = new IntentFilter();
    filter.addAction(Intent.ACTION_DOCK_EVENT);
    mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
}

總而言之在SystemReady方法中完成的主要工作如下:

  • 1.獲取與PowerManagerServcie相關(guān)的系統(tǒng)服務(wù)以及本地服務(wù);
    獲取屏幕最大,最小以及默認(rèn)亮度值;
  • 2.創(chuàng)建SensorManager 對(duì)象,用于和SensorService交互;
  • 3.創(chuàng)建Notifier對(duì)象,用于通知系統(tǒng)中電源狀態(tài)的改變;
  • 4.創(chuàng)建WirelessChargerDetector對(duì)象,用于檢測(cè)無(wú)線充電的傳感器(市面上支持的手機(jī)較少)
  • 5.調(diào)用DisplayManagerService的initPowerManagement()方法來(lái)初始化Power顯示模塊。
  • 6.注冊(cè)SettingsObserver監(jiān)聽(tīng)系統(tǒng)設(shè)置的變化

userActivity
userActivity是定義在PowerManager中的SystemApi,用戶向PowerManagerService報(bào)告用戶活動(dòng),以更新PowerManagerService內(nèi)部時(shí)間/狀態(tài)值,推遲系統(tǒng)休眠的時(shí)間。
PowerManager中userActivity請(qǐng)求調(diào)用服務(wù)端PowerManagerService BinderService的userActivity,即調(diào)用內(nèi)部方法userActivityNoUpdateLocked

private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {
    // 如果發(fā)生時(shí)間是上一次休眠或喚醒前,或當(dāng)前沒(méi)有開(kāi)機(jī)完成到systemReady,不采取操作直接返回
    if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
            || !mBootCompleted || !mSystemReady) {
        return false;
    }

    try {
        // 更新mLastInteractivePowerHintTime時(shí)間
        if (eventTime > mLastInteractivePowerHintTime) {
            powerHintInternal(POWER_HINT_INTERACTION, 0);
            mLastInteractivePowerHintTime = eventTime;
        }

        // 通過(guò)mNotifier通知BatteryStats UserActivity事件
        mNotifier.onUserActivity(event, uid);

        if (mUserInactiveOverrideFromWindowManager) {
            mUserInactiveOverrideFromWindowManager = false;
            mOverriddenTimeout = -1;
        }

        // 如果系統(tǒng)處于休眠狀態(tài),不進(jìn)行處理
        if (mWakefulness == WAKEFULNESS_ASLEEP
                || mWakefulness == WAKEFULNESS_DOZING
                || (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) {
            return false;
        }

        // 根據(jù)flag是否在已變暗的情況下是否重啟活動(dòng)超時(shí)更新mLastUserActivityTimeNoChangeLights或mLastUserActivityTime
        // 并且設(shè)置mDirty DIRTY_USER_ACTIVITY
        if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {
            if (eventTime > mLastUserActivityTimeNoChangeLights
                    && eventTime > mLastUserActivityTime) {
                mLastUserActivityTimeNoChangeLights = eventTime;
                mDirty |= DIRTY_USER_ACTIVITY;
                return true;
            }
        } else {
            if (eventTime > mLastUserActivityTime) {
                mLastUserActivityTime = eventTime;
                mDirty |= DIRTY_USER_ACTIVITY;
                return true;
            }
        }
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_POWER);
    }
    return false;
}

三、 應(yīng)用場(chǎng)景

例如:長(zhǎng)連接需要在后臺(tái)服務(wù)需要持續(xù)在線;安卓系統(tǒng)底層優(yōu)化策略會(huì)在系統(tǒng)休眠這段時(shí)間調(diào)整CPU的運(yùn)作,我們需要將應(yīng)用保持CPU一直運(yùn)轉(zhuǎn)。
mqtt或者websocket等長(zhǎng)連接框架就需要如此!

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock w1 = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "MyTag");
w1.acquire();
//在這個(gè)過(guò)程,屏幕會(huì)保持光亮! 
//或者網(wǎng)絡(luò)協(xié)議執(zhí)行心跳包
w1.release();

上述newWakeLock( )的第一個(gè)flag標(biāo)記,這些標(biāo)記不同程度的影響系統(tǒng)電源.
這些標(biāo)記都是獨(dú)占的,并且每次只能指定其中一個(gè)。

  • PARTIAL_WAKE_LOCK:保持CPU 運(yùn)轉(zhuǎn),屏幕和鍵盤燈有可能是關(guān)閉的。
  • SCREEN_DIM_WAKE_LOCK:保持CPU 運(yùn)轉(zhuǎn),允許保持屏幕顯示但有可能是灰的,允許關(guān)閉鍵盤燈
  • SCREEN_BRIGHT_WAKE_LOCK:保持CPU 運(yùn)轉(zhuǎn),允許保持屏幕高亮顯示,允許關(guān)閉鍵盤燈
  • FULL_WAKE_LOCK:保持CPU 運(yùn)轉(zhuǎn),保持屏幕高亮顯示,鍵盤燈也保持亮度

四、 控制系統(tǒng)休眠

Android設(shè)備的休眠和喚醒主要基于WakeLock機(jī)制。WakeLock是一種上鎖機(jī)制,只要有進(jìn)程獲得了WakeLock鎖系統(tǒng)就不會(huì)進(jìn) 入休眠。例如,在下載文件或播放音樂(lè)時(shí),即使休眠時(shí)間到了,系統(tǒng)也不能進(jìn)行休眠。WakeLock可以設(shè)置超時(shí),超時(shí)后會(huì)自動(dòng)解鎖。

應(yīng)用使用WakeLock功能前,需要先使用new WakeLock()接口創(chuàng)建一個(gè)WakeLock類對(duì)象,然后調(diào)用它的acquire()方法禁止系統(tǒng)休眠,應(yīng)用完成工作后調(diào)用release()方法來(lái)恢復(fù)休眠機(jī)制,否則系統(tǒng)將無(wú)法休眠,直到耗光所有電量。

WakeLock類中實(shí)現(xiàn)acquire()release()方法實(shí)際上是調(diào)用了PowerManagerServiceacquireWakeLock()releaseWakeLock()方法。

updatePowerStateLocked()PowerManagerService的核心函數(shù);在執(zhí)行完申請(qǐng)鎖,釋放鎖,用戶事件,強(qiáng)制喚醒/睡眠等操作都需要調(diào)用updatePowerStateLocked()來(lái)更新電源狀態(tài)

wakelock
Wakelock是android系統(tǒng)上特有的電源管理機(jī)制,只要有應(yīng)用拿著這個(gè)鎖,系統(tǒng)就不能進(jìn)入睡眠狀態(tài),在上層不同的應(yīng)用程序可以持有多個(gè)不同的wakelock鎖,但是反映到底層就只有三種:控制系統(tǒng)休眠PowerManagerService.WakeLock,控制屏幕顯示的PowerManagerService.Display和控制電源狀態(tài)改變通知的PowerManagerService.Broadcasts

PowerManagerService有acquire()加鎖release()解鎖`兩種狀態(tài),加鎖有兩種方式:

  • 第一種是永久的鎖住,這樣的鎖除非顯式的放開(kāi),否則是不會(huì)解鎖的,所以這種鎖用起來(lái)要非常的小心(默認(rèn))。
    acquire():申請(qǐng)wakelock永久鎖(默認(rèn)),需要手動(dòng)release
  • 第二種鎖是超時(shí)鎖,這種鎖會(huì)在鎖住后一段時(shí)間解鎖。
    acquire(long timeout):申請(qǐng)wakelock超時(shí)鎖,timeout為設(shè)置的超時(shí)時(shí)間,超時(shí)自動(dòng)release掉該wakelock。

應(yīng)用程序在使用wakelock前,必須在其manifest.xml文件中注冊(cè)android.permission.WAKE_LOCK權(quán)限;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容