簡(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í)圖
電源管理架構(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ā)布了BinderService
,LocalService
分別供其他進(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)用了PowerManagerService
的acquireWakeLock()
和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)限;