两个处理器
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