androidwakelock_Android中的WakeLock

androidwakelock_Android中的WakeLock两个处理器ApplicationProcessor(AP):AP是ARM架构的处理器,用于运行Linux+Android系统。BasebandProcesspr(BP):BP用于运行实时操作系统(RTOS),运行手机射频通信控制软件。非通话时间BP能耗很低;而AP由于需要运行操作系统、用户界面和应用程序,只要处于非休眠状态能耗相对BP要高出很多,执行图形运算会更高。让系统保持“清醒”当手机…

两个处理器

Application Processor (AP):

AP是ARM架构的处理器,用于运行Linux+Android系统。

Baseband Processpr (BP):

BP用于运行实时操作系统(RTOS),运行手机射频通信控制软件。

非通话时间BP能耗很低;而AP由于需要运行操作系统、用户界面和应用程序,只要处于非休眠状态能耗相对BP要高出很多,执行图形运算会更高。

让系统保持“清醒”

当手机灭屏状态下保持一段时间后,系统会进入休眠,一些后台任务比如网络下载,播放音乐会得不到正常的执行。WakeLock API可以确保应用程序中关键代码的正确执行,使应用程序有能力控制AP的休眠状态。

一种锁机制

当应用申请了WakeLock,WakeLock会阻止AP挂起,系统无法进入休眠,即使在灭屏的状态下,应用要执行的任务依然不会被打断。当所有WakeLock被释放(解锁/超时),系统会挂起启动休眠机制进入休眠。

使用WakeLock

PowerManager pm= (PowerManager) this.getSystemService(Context.POWER_SERVICE);

PowerManager.WakeLock wakeLock=pm.newWakeLock(PowerManager.ON_AFTER_RELEASE|PowerManager.PARTIAL_WAKE_LOCK,”Tag”);

//申请WakeLock

wakeLock.acquire();

//… do work…

//释放wakeLock

//当使用wakeLock.acquire(timeout)的方式时系统会自动释放

wakeLock.release();

WakeLock的分类和Flag

分类

PARTIAL_WAKE_LOCK: 灭屏,关闭键盘背光的情况下,CPU依然保持运行。

PROXIMITY_SCREEN_OFF_WAKE_LOCK: 基于距离感应器熄灭屏幕。最典型的运用场景是我们贴近耳朵打电话时,屏幕会自动熄灭。

SCREEN_DIM_WAKE_LOCK

SCREEN_BRIGHT_WAKE_LOCK

FULL_WAKE_LOCK

三种过时方法,它们的目的是保持屏幕常亮。

官方建议使用:

//不需要申请WakeLock和权限

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

DOZE_WAKE_LOCK/DRAW_WAKE_LOCK: 隐藏的分类,系统级别才会用到。

Flag

ACQUIRE_CAUSES_WAKEUP: 点亮屏幕,比如应用接收到通知后,屏幕亮起。

ON_AFTER_RELEASE: 释放WakeLock后,屏幕不马上熄灭。

UNIMPORTANT_FOR_LOGGING: 隐藏的flag,系统级别才会用到。

其他方法

//判断是否已经获取WakeLock

wakeLock.isHeld();

//是否引用计数器

wakeLock.setReferenceCounted(false);

默认true开启引用计数器,如果一个WakeLock acquire了多次也必须release多次才能释放掉。但是如果释放次数比acquire多则会抛出RuntimeException(Tag)异常。

false关闭引用计数器时,无论 acquire() 了多少次,只要通过一次 release()即可解锁。

PS:PowerManager.WakeLock 的计数机制并只是对同一把锁被申请/释放的次数进行了统计再正去操作。

简单的debug方法

测试代码

/**

* @Author: 吃茶泡饭丶

* @CreateDate: 2018/9/3

*/

public class WakeLockActivity extends BaseActivity {

private PowerManager.WakeLock wakeLock;

@Override

protected void onResume() {

PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);

wakeLock = pm.newWakeLock(PowerManager.ON_AFTER_RELEASE

| PowerManager.PARTIAL_WAKE_LOCK, “Tag”);

//申请WakeLock

wakeLock.acquire();

super.onResume();

}

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_wake_lock);

//… do work…

}

@Override

protected void onPause() {

//释放wakeLock

//当使用wakeLock.acquire(timeout)的方式时系统会自动释放

wakeLock.release();

super.onPause();

}

}

通过adb 命令

adb shell dumpsys “power|grep -i wake”

and

$ adb shell dumpsys power|grep -i wake

进入onResume申请WakeLock,dumpsys的信息

no_cached_wake_locks=true

mWakefulness=Awake

mWakefulnessChanging=false

mWakeLockSummary=0x1

mLastWakeTime=509144080 (30113 ms ago)

mHoldingWakeLockSuspendBlocker=true

mWakeUpWhenPluggedOrUnpluggedConfig=true

mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig=false

mDoubleTapWakeEnabled=false

Wake Locks: size=1

mLock:176961948 PARTIAL_WAKE_LOCK ‘Tag’ ON_AFTER_RELEASE ACQ=-2s581ms (uid=10155 pid=26429)

PowerManagerService.WakeLocks: ref count=1

Proxyed WakeLocks State

进入onPause释放WakeLock,dumpsys的信息

no_cached_wake_locks=true

mWakefulness=Awake

mWakefulnessChanging=false

mWakeLockSummary=0x0

mLastWakeTime=509144080 (271089 ms ago)

mHoldingWakeLockSuspendBlocker=false

mWakeUpWhenPluggedOrUnpluggedConfig=true

mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig=false

mDoubleTapWakeEnabled=false

Wake Locks: size=0

PowerManagerService.WakeLocks: ref count=0

Proxyed WakeLocks State

准确的debug方法

使用battery historian 工具,在应用运行一段时间后抓取bugreport查看wakelock申请情况。

https://github.com/google/battery-historian

需要搭建GO语言环境

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/35213.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注