• PowerManagerService(一)— 初始化


    1. 简介

      PowerManagerServcie是android系统电源管理的核心服务,它在Framework层建立起一个策略控制方案,向下决策HAL层以及kernel层来控制设备待机状态,主要功能是控制系统待机状态,屏幕显示,亮度调节,光线/距离传感器的控制等。

      除了与应用程序交互之外,还要与系统中其它模块配合,在提供良好的能源管理同时提供友好的用户体验。比如听音乐时持续保持系统唤醒,应用通知来临唤醒手机屏幕等场景

      分析一个服务,首先要从它对应用层提供的api PowerManager入手,观察提供了哪些接口调用;

    • Wakeup():强制系统从睡眠状态唤醒,此接口对应用是不开放的,应用想唤醒系统必须通过设置亮屏标志(后面即将讲到);
    • gotoSleep():强制系统进入到睡眠状态,此接口也是应用不开放。
    • userActivity():向PowerManagerService报告影响系统休眠的用户活动,重计算灭屏时间,背光亮度等,例如触屏,划屏,power键等用户活动;
    • Wakelock:wakelock是PowerManager的一个内部类,提供了相关的接口来操作wakelock锁,比如newWakeLock()方法来创建wakelock锁,acquire()和release()方法来申请和释放锁。下面例子有介绍!
    • isDeviceIdleMode():返回设备当前的状态,如果处于Idle状态,则返回true,Idle状态是在手机长时间没有被使用以及没有运动的情况下,手机进入到一种Doze低功耗的模式下,这种状态下手机可能会关掉网络数据访问,可以通过监视DEVICE_IDLE_MODE_CHANGED这个广播信息,来监控手机状态的改变

    1.1 系统层级图

    在这里插入图片描述

    1.2 电源管理架构

    主要分为四个层次:

    • 应用接口层:PowerManager.java中开放给应用一系列接口,应用可以调用PM的接口申请wakelock,唤醒系统,使系统进入睡眠等操作;
    • Framework层:PowerManagerService.java计算系统中和Power相关的计算,是整个电源管理的决策系;
    • HAL层:该层只有一个power.c文件,该文件通过上层传下来的参数,向/sys/power/wake_lock或者/sys/power/wake_unlock文件节点写数据来与kernel进行通信,主要功能是申请/释放锁,维持屏幕亮灭。
    • Kernel层:内核层实现电源管理的方案主要包含三个部分:
      Kernel/power/:实现了系统电源管理框架机制。
      Arch/arm(ormips or powerpc)/mach-XXX/pm.c:实现对特定板的处理器电源管理。
      drivers/power:是设备电源管理的基础框架,为驱动提供了电源管理接口。

    2. 初始化

      跟其他系统服务一样,PowerManagerService也是继承于SystemService并通过SystemServer启动。

    2.1 SystemServer启动PowerManagerService服务

    frameworks/base/services/java/com/android/server/SystemServer.java

    private void startBootstrapServices() {
      ......
      mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
      ......
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.2 PowerManagerService构造

    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;
    		//创建消息处理线程,并启动
            mHandlerThread = new ServiceThread(TAG,
                    Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
            mHandlerThread.start();
    		//创建Hanlder对象处理消息
            mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
            mConstants = new Constants(mHandler);
            mAmbientDisplayConfiguration = new AmbientDisplayConfiguration(mContext);
            mBatterySaverPolicy = new BatterySaverPolicy(mHandler);
    
            synchronized (mLock) {
                //创建"PowerManagerService.WakeLocks"的SuspendBlocker
                mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
                // 创建"PowerManagerService.Display"的SuspendBlocker
                mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
                // 请求DisplaySuspendBlocker,禁止系统进入休眠
                mDisplaySuspendBlocker.acquire();
                mHoldingDisplaySuspendBlocker = true;
                mHalAutoSuspendModeEnabled = false;
                mHalInteractiveModeEnabled = true;
                // 设置mWakefulness为唤醒状态
                mWakefulness = WAKEFULNESS_AWAKE;
    
                sQuiescent = SystemProperties.get(SYSTEM_PROPERTY_QUIESCENT, "0").equals("1");
                // 进入到native层初始化
                nativeInit();
                nativeSetAutoSuspend(false);
                nativeSetInteractive(true);
                nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
            }
        }
        ......
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

      PowerManagerService构造函数中首先创建了处理消息的进程及对应的handler对象以进行消息处理,然后创建SuspendBlocker对象,用于WakeLocks与Display,并设置mWakefulness的初始状态为WAKEFULNESS_AWAKE,最后进入到native层初始化。下面先看一下关于mWakefulness的定义。

    frameworks/base/core/java/android/os/PowerManagerInternal.java

    /**
     * 设备处于休眠状态,只能被wakeUp()唤醒.
     */
    public static final int WAKEFULNESS_ASLEEP = 0;
    
    /**
     * 设备处于正常工作(fully awake)状态.
     */
    public static final int WAKEFULNESS_AWAKE = 1;
    
    /**
     * 设备处于播放屏保状态.
     */
    public static final int WAKEFULNESS_DREAMING = 2;
    
    /**
     * 设备处于doze状态,只有低耗电的屏保可以运行,其他应用被挂起.
     */
    public static final int WAKEFULNESS_DOZING = 3;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

      继续回到PowerManagerService构造函数的native初始化中,首先来看nativeInit的实现。

    frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp

    static void nativeInit(JNIEnv* env, jobject obj) {
       // 创建一个全局对象,引用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));
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

      nativeInit的主要任务时装载power模块,该模块由厂商实现,以高通为例,如下。

    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,
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

      power_module中实现了init,powerHint,setInteractive,nativeInit最终调用到HAL power模块的power_init具体实现中。接着看native初始化nativeSetAutoSuspend的实现。

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

      同nativeInit一样,最终都是调用到HAL power模块的具体实现中。

    3. 启动

      下面继续看PowerManagerService在系统启动过程中回调onStart(),onBootPhase(),systemReady()的实现。

    3.1 启动服务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 {
        ......
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

      onStart()中发布了BinderServiceLocalService分别供其他进程,进程内其他服务调用,并将PowerManagerService加入到Watchdog监控中。

    3.2 启动服务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();
                // 设置mBootCompleted状态
                mBootCompleted = true;
                mDirty |= DIRTY_BOOT_COMPLETED;
                // 更新userActivity及PowerState,后面分析
                userActivityNoUpdateLocked(
                        now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
                updatePowerStateLocked();
                // 执行mBootCompletedRunnables中的runnable方法
                if (!ArrayUtils.isEmpty(mBootCompletedRunnables)) {
                    Slog.d(TAG, "Posting " + mBootCompletedRunnables.length + " delayed runnables");
                    for (Runnable r : mBootCompletedRunnables) {
                        BackgroundThread.getHandler().post(r);
                    }
                }
                mBootCompletedRunnables = null;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

      onBootPhase()中主要设置mBootCompleted状态,更新PowerState状态,并执行mBootCompletedRunnables中的runnables方法(低电量模式会设置)。

    3.3 启动服务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);
            // 获取屏幕默认,最大,最小亮度
            mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
            mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
            mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();
            // 获取SensorManager
            SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());
    
            mBatteryStats = BatteryStatsService.getService();
            // 创建Notifier对象,用于广播power state的变化
            mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
                    mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
                    mPolicy);
            // 无线充电检测
            mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
                    createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
                    mHandler);
            // 监听设置的变化
            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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79

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

    • 1.获取与PowerManagerServcie相关的系统服务以及本地服务;
      获取屏幕最大,最小以及默认亮度值;
    • 2.创建SensorManager 对象,用于和SensorService交互;
    • 3.创建Notifier对象,用于通知系统中电源状态的改变;
    • 4.创建WirelessChargerDetector对象,用于检测无线充电的传感器(市面上支持的手机较少)
    • 5.调用DisplayManagerService的initPowerManagement()方法来初始化Power显示模块。
    • 6.注册SettingsObserver监听系统设置的变化

    3.4 userActivity

      userActivity是定义在PowerManager中的SystemApi,用户向PowerManagerService报告用户活动,以更新PowerManagerService内部时间/状态值,推迟系统休眠的时间。
    PowerManager中userActivity请求调用服务端PowerManagerService BinderService的userActivity,即调用内部方法userActivityNoUpdateLocked

    private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {
        // 如果发生时间是上一次休眠或唤醒前,或当前没有开机完成到systemReady,不采取操作直接返回
        if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
                || !mBootCompleted || !mSystemReady) {
            return false;
        }
    
        try {
            // 更新mLastInteractivePowerHintTime时间
            if (eventTime > mLastInteractivePowerHintTime) {
                powerHintInternal(POWER_HINT_INTERACTION, 0);
                mLastInteractivePowerHintTime = eventTime;
            }
    
            // 通过mNotifier通知BatteryStats UserActivity事件
            mNotifier.onUserActivity(event, uid);
    
            if (mUserInactiveOverrideFromWindowManager) {
                mUserInactiveOverrideFromWindowManager = false;
                mOverriddenTimeout = -1;
            }
    
            // 如果系统处于休眠状态,不进行处理
            if (mWakefulness == WAKEFULNESS_ASLEEP
                    || mWakefulness == WAKEFULNESS_DOZING
                    || (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) {
                return false;
            }
    
            // 根据flag是否在已变暗的情况下是否重启活动超时更新mLastUserActivityTimeNoChangeLights或mLastUserActivityTime
            // 并且设置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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    4. 应用场景

      例如:长连接需要在后台服务需要持续在线;安卓系统底层优化策略会在系统休眠这段时间调整CPU的运作,我们需要将应用保持CPU一直运转。

    mqtt或者websocket等长连接框架就需要如此!

    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock w1 = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "MyTag");
    w1.acquire();
    //在这个过程,屏幕会保持光亮! 
    //或者网络协议执行心跳包
    w1.release();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

      上述newWakeLock( )的第一个flag标记,这些标记不同程度的影响系统电源.
      这些标记都是独占的,并且每次只能指定其中一个。

    • PARTIAL_WAKE_LOCK:保持CPU 运转,屏幕和键盘灯有可能是关闭的。
    • SCREEN_DIM_WAKE_LOCK:保持CPU 运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯
    • SCREEN_BRIGHT_WAKE_LOCK:保持CPU 运转,允许保持屏幕高亮显示,允许关闭键盘灯
    • FULL_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度

    5. 控制系统休眠

      Android设备的休眠和唤醒主要基于WakeLock机制。WakeLock是一种上锁机制,只要有进程获得了WakeLock锁系统就不会进 入休眠。例如,在下载文件或播放音乐时,即使休眠时间到了,系统也不能进行休眠。WakeLock可以设置超时,超时后会自动解锁,具体关于wake lock的介绍后面会另写一篇,此处仅作简单介绍。

      应用使用WakeLock功能前,需要先使用new WakeLock()接口创建一个WakeLock类对象,然后调用它的acquire()方法禁止系统休眠,应用完成工作后调用release()方法来恢复休眠机制,否则系统将无法休眠,直到耗光所有电量。

      WakeLock类中实现acquire()release()方法实际上是调用了PowerManagerServiceacquireWakeLock()releaseWakeLock()方法。

      updatePowerStateLocked()PowerManagerService的核心函数;在执行完申请锁,释放锁,用户事件,强制唤醒/睡眠等操作都需要调用updatePowerStateLocked()来更新电源状态

    5.1 wakelock

      Wakelock是android系统上特有的电源管理机制,只要有应用拿着这个锁,系统就不能进入睡眠状态,在上层不同的应用程序可以持有多个不同的wakelock锁,但是反映到底层就只有三种:控制系统休眠PowerManagerService.WakeLock,控制屏幕显示的PowerManagerService.Display和控制电源状态改变通知的PowerManagerService.Broadcasts

      PowerManagerServiceacquire()加锁release()解锁两种状态,加锁有两种方式:

    • 第一种是永久的锁住,这样的锁除非显式的放开,否则是不会解锁的,所以这种锁用起来要非常的小心(默认)。
      acquire():申请wakelock永久锁(默认),需要手动release
    • 第二种锁是超时锁,这种锁会在锁住后一段时间解锁。
      acquire(long timeout):申请wakelock超时锁,timeout为设置的超时时间,超时自动release掉该wakelock。

      应用程序在使用wakelock前,必须在其manifest.xml文件中注册android.permission.WAKE_LOCK权限;

  • 相关阅读:
    强化学习实战——Motion Imitation环境配置+所遇问题(win10)
    【毕业设计】基于javaEE+SSH+oracle的健康管理系统设计与实现(毕业论文+程序源码)——健康管理系统
    Jenkins详细安装配置部署--超详细
    【Web开发】CSS教学(超详细,满满的干货)
    【原创教程】EPLAN如何制作专属的封面
    【Unity】RenderFeature应用(简单场景扫描效果)
    Node.js 学习笔记 fs、path、http模块;模块化;包;npm
    Spring Cloud Zookeeper 升级为Spring Cloud Kubernetes
    100道Java高频面试题(阿里面试官整理)
    vue中addEventListener监听不到,原来是最外层没有设置长宽
  • 原文地址:https://blog.csdn.net/IT_xiao_bai0516/article/details/125498014