PowerManagerService分析之PARTIAL_WAKE_LOCK

为什么申请了PARTIAL_WAKE_LOCK系统不会进str?

1 . acquireWakeLockInternal 把 wakelock加到mWakeLocks中;

2. updatePowerStateLocked -> updateWakeLockSummaryLocked -> getWakeLockSummaryFlags

把PowerManager.PARTIAL_WAKE_LOCK转化为mWakelockSummary = WAKE_LOCK_CPU;

3. updatePowerStateLocked -> updateSuspendBlockerLocked

    // The suspend blocker used to keep the CPU alive when an application has acquired
    // a wake lock.
    private final SuspendBlocker mWakeLockSuspendBlocker;

    private void updateSuspendBlockerLocked() {
        //WAKE_LOCK_CPU的作用在这里
        boolean needWakeLockSuspendBlocker = ((mWakeLockSummary & WAKE_LOCK_CPU) != 0);
        ...
        ...
        // First acquire suspend blockers if needed.
        if (needWakeLockSuspendBlocker && !mHoldingWakeLockSuspendBlocker) {
            //SuspendBlocker申请,这样就把WAKE_LOCK_CPU和不进str联系起来了,
            //由于SuspendBlocker,所以进不了str
            mWakeLockSuspendBlocker.acquire();
            mHoldingWakeLockSuspendBlocker = true;
        }
        ...
        ...
        // Then release suspend blockers if needed.
        if (!needWakeLockSuspendBlocker && mHoldingWakeLockSuspendBlocker) {
            mWakeLockSuspendBlocker.release();
            mHoldingWakeLockSuspendBlocker = false;
        }

    }


    public PowerManagerService(context){
    ....
            synchronized (mLock) {
            //在构造函数中创建
            mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");
            mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");
            mDisplaySuspendBlocker.acquire();
            mHoldingDisplaySuspendBlocker = true;
            mHalAutoSuspendModeEnabled = false;
            mHalInteractiveModeEnabled = true;

            mWakefulness = WAKEFULNESS_AWAKE;

            sQuiescent = SystemProperties.get(SYSTEM_PROPERTY_QUIESCENT, "0").equals("1");

            nativeInit();
            nativeSetAutoSuspend(false);
            nativeSetInteractive(true);
            nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
        }
    ....
    }

dumpsys power可以看到 wakelock和suspendblocker的数量

Wake Locks: size=6
  PARTIAL_WAKE_LOCK              'wakeup_WakelockTag' ACQ=-2h23m42s456ms LONG (uid=1000 pid=5725)
  PARTIAL_WAKE_LOCK              'LanHostRuntime' ON_AFTER_RELEASE ACQ=-4m13s653ms LONG (uid=1000 pid=15503)
  SCREEN_BRIGHT_WAKE_LOCK        'com.gala.uniplayer.WakeModeSetter' ON_AFTER_RELEASE ACQ=-2s261ms (uid=10006 pid=8557)
  PARTIAL_WAKE_LOCK              'AudioMix' ACQ=-1s946ms (uid=1041)
  PARTIAL_WAKE_LOCK              'AudioMix' ACQ=-623ms (uid=1041 ws=WorkSource{10006})
  SCREEN_BRIGHT_WAKE_LOCK        'WindowManager' ON_AFTER_RELEASE ACQ=-845ms (uid=1000 pid=3320 ws=WorkSource{10006})

Suspend Blockers: size=4
  PowerManagerService.WakeLocks: ref count=1
  PowerManagerService.Display: ref count=1
  PowerManagerService.Broadcasts: ref count=0
  PowerManagerService.WirelessChargerDetector: ref count=0

奇怪的是,app申请一个keep_screen_on, system_server进程windowmanager就会申请一个,退出的时候两个都没了,成对出现,怕是app被杀吗?测试了下,app被杀所有相关wakelock都释放了。

<think>嗯,用户现在问的是Partial Wakelock的含义及其在安卓手机功耗分析中的作用,还有它的中文翻译。首先,我需要回顾一下之前提供的功耗分析内容,特别是关于WakeLock的部分。用户之前的问题是关于安卓手机功耗分析工具和优化方法,其中提到了Partial Wakelock持有时间过长的问题。所以现在需要更详细地解释这个概念。 根据引用中的信息,比如引用[3]和[5],WakeLock是应用通过PowerManager获取的,用来阻止设备进入休眠状态。Partial Wakelock属于其中一种类型。需要明确它的具体作用,比如保持CPU运行但允许屏幕关闭。同时,用户可能需要了解它与其他类型的WakeLock(比如FULL_WAKE_LOCK)的区别。 接下来,用户提到中文翻译的问题。Partial Wakelock通常翻译为“部分唤醒锁”,但需要确认是否有其他常见译名,比如“不完全唤醒锁”之类的。不过根据常见的文献和文档,“部分唤醒锁”是比较标准的翻译,需要指出这一点。 在功耗分析中的作用方面,用户可能想知道为什么Partial Wakelock会导致功耗问题。例如,如果应用在后台持有Partial Wakelock,即使屏幕关闭,CPU也会保持活动状态,导致电池消耗增加。结合之前提到的Battery Historian工具,可以说明如何通过分析工具检测到这种情况,比如检查持有时间过长的WakeLock。 另外,引用中提到的代码示例和调试方法,比如打开debug开关、使用dumpsys power命令,这些都是开发者在实际分析中会用到的技术。可能需要解释这些步骤如何帮助定位Partial Wakelock的问题,比如通过日志查找acquireWakeLockInternal关键字。 用户可能还想知道如何正确使用和释放Partial Wakelock以避免功耗问题。引用[5]中的代码示例展示了获取和释放WakeLock的正确方法,需要强调在不再需要时及时释放,否则会导致资源泄露和电池消耗。 还要注意用户是否有更深层的需求,比如他们可能在开发中遇到了WakeLock未释放的问题,导致应用耗电高,所以需要了解如何分析和解决。因此,回答中需要包含实际的应用场景和优化建议,帮助用户理解如何在实际操作中处理Partial Wakelock。 最后,确保回答结构清晰,分点说明定义、作用、分析方法和优化建议,同时正确引用之前的资料,比如引用[1]、[3]、[4]、[5]中的相关内容,来支持每个部分的解释。</think>### Partial Wakelock 的定义与功耗分析意义 #### 一、Partial Wakelock 的中文翻译 - **直译**:部分唤醒锁 - **技术文档常用译法**:不完全唤醒锁(保留CPU运行但允许屏幕关闭的特性) #### 二、核心定义与特性 1. **功能本质** Partial Wakelock(`PowerManager.PARTIAL_WAKE_LOCK`)是一种允许**CPU保持运行**但**允许屏幕/键盘熄灭**的电源管理机制[^3][^5]。 - 示例代码: ```java PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "BackgroundTask"); ``` 2. **与其他WakeLock的对比** | 类型 | CPU状态 | 屏幕状态 | 典型场景 | |-----------------------|---------|----------------|------------------------| | `PARTIAL_WAKE_LOCK` | 保持活跃| 关闭 | 后台音乐播放、数据同步 | | `FULL_WAKE_LOCK` | 保持活跃| 强制亮屏+高亮度| 视频通话、导航应用 | | `SCREEN_DIM_WAKE_LOCK`| 保持活跃| 保持低亮度常亮 | 阅读类应用 | #### 三、功耗分析中的关键作用 1. **耗电根源定位** - Partial Wakelock 若未及时释放(例如后台服务未调用`release()`),会导致**CPU持续唤醒**,显著增加待机功耗[^4]。 - **Battery Historian报告指标**: - `Partial Wakelock`持有时间占比 - 与`Mobile Radio Active`或`Sensor`事件的关联性[^1] 2. **异常场景分析** - **案例1**:后台定位服务未释放Partial Wakelock,导致设备无法进入深度睡眠(`Deep Sleep`状态缺失)。 - **案例2**:消息推送服务频繁唤醒CPU,触发`Mobile Network`同步(可通过合并请求优化)。 #### 四、调试与分析工具 1. **代码层验证** - 打开PowerManagerService调试开关(`DEBUG = true`),通过`logcat`搜索`acquireWakeLockInternal`追踪锁的申请与释放链[^1]。 - 使用`adb shell dumpsys power`查看当前活跃的WakeLock列表及持有者信息。 2. **堆栈溯源** - 若发现未释放的Partial Wakelock,可通过`Binder`代理反向定位调用方代码(参考`releaseWakeLockInternal`逻辑[^4])。 - 示例调试输出: ``` Wake Locks: size=2 PARTIAL_WAKE_LOCK 'AudioMix' ACQ=123ms (uid=10103, pid=489) PARTIAL_WAKE_LOCK 'MyWakeLockTag' ACQ=60000ms (uid=10054, pid=672) ``` #### 五、最佳实践与优化 1. **使用规范** - 确保`acquire()`与`release()`成对调用,推荐`try-finally`代码块: ```java try { wakeLock.acquire(); // 执行后台任务 } finally { if (wakeLock.isHeld()) { wakeLock.release(); } } ``` 2. **替代方案** - 使用`WorkManager`或`JobScheduler`替代自主轮询,减少主动唤醒需求。 - 对周期性任务设置`setExactAndAllowWhileIdle()`限制触发频率。 --- ### 相关问题 1. 如何通过Battery Historian报告识别Partial Wakelock泄漏? 2. 在Android 12+的省电策略下,Partial Wakelock的使用有哪些新限制? 3. 哪些系统服务可能隐式持有Partial Wakelock?如何排查? --- **总结**:Partial Wakelock是平衡功能与功耗的关键工具,但滥用会导致**异常唤醒链**。需结合代码审查、系统日志与功耗分析工具实现精准管控[^3][^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值