手机锁屏之后 Linux Deploy 休眠问题
我在安卓手机安装了 Linux deploy,为了使 Linux deploy中的 Linux 稳定运行,已经设置了取消电池优化,并且也锁定了 Linux deploy 的后台,但是在手机息屏一段时间以后还是会出现断网或者ssh连接缓慢的问题。
我设置了每分钟都会将当前时间输出到文件中的定时任务,但是在息屏后一段时间以后脚本中的数据就不正常了。后面每一分钟有三条,而是输出时间有比较明显的延后现象。
文件中数据如下:
|
|
解决办法
关闭 Doze 和 App Standby
adb shell dumpsys deviceidle disable
adb shell am set-inactive ru.meefik.linuxdeploy false
创建定时任务,让应用一直持有唤醒锁:
|
|
应用被操作时,如果没有唤醒锁,就会申请一个60分钟的唤醒锁,60分钟以后唤醒锁会被释放,程序会进入睡眠状态,如果时间较久,应用进入深度睡眠,进程会被挂起,此时进入ssh会非常慢,linux deploy 源码的 MainActivity.java onResume() 中有以下代码:
|
|
相关命令 adb 命令:
|
|
下面是对于 Doze 、App Standby 和 Wake Lock 的解释说明:
Doze 睡眠模式
从Android6.0开始,Android提供了两种省电延长电池寿命的功能:Doze和App Standby
表现形式:当设备没有连接到电源,设备进入Doze模式时,系统将通过延迟最近用户没有使用的应用程序的后台CPU运作及网络活动,让应用程序处于App Standby状态,以此来减少电池消耗。谷歌表示,在Nexus5和Nexus6上测试,当屏幕处于关闭状态,平均续航时间提高30%;
版本要求:Android6.0(API level 23)及其更高版本;
设备进入Doze睡眠模式时机(满足以下三个条件):
- 设备未连接电源充电
- 屏幕关闭
- 用户不操作设备一段时间(首先进入浅度睡眠,设备静止约30分钟进入深度睡眠)
Doze模式下应用程序有什么变化:
1.网络访问被挂起
-
Wake Locks被无视
-
AlarmManager被推迟到下一个maintenance window窗口, 除非使用AlarmManager新方法:setAndAllowWhileIdle(),setExactAndAllowWhileIdle(),setAlarmClock()
-
WiFi扫描被停止
-
SyncAdapter同步工作被停止
-
JobScheduler定时任务被停止
Doze模式的五种状态:
ACTIVE:手机设备处于激活活动状态
INACTIVE:屏幕关闭进入非活动状态
IDLE_PENDING:每隔30分钟让App进入等待空闲预备状态
IDLE:空闲状态
IDLE_MAINTENANCE:处理挂起任务
Doze期间提供间隔一小段时间(30s)供应用程序使用网络和处理挂起的活动。
系统进入Doze模式后,系统会隔一段时间处理正在挂起的任务,随着时间推移,后面间隔的时间会越来越长,以此来减少电量消耗
退出Doze模式(系统退出休眠,所有的应用程序恢复正常活动):
- 用户唤醒装置移动,打开屏幕
- 或者设备连接电源
阻止电池优化(白名单)
Android6.0及更高版本提供电池优化白名单,App加入白名单可逃脱Doze和App Standby限制, 处于白名单中的App也会受到一定限制: Jobs和Syncs以及常规Alarms也会被推迟;
用户手动设置App进入白名单: 设置>电池>电池优化白名单
App Standby 应用待机模式
当用户有一段时间未主动使用应用时,系统判定该应用处于空闲状态。以下情况除外:
-
用户显式启动应用。
-
应用当前有一个进程位于前台(表现为 Activity 或前台服务形式,或被另一 Activity 或前台服务占用)。
-
用户可在锁屏或通知栏中看到的通知。
-
系统应用。
当用户将设备插入电源时,系统将退出待机状态,从而让它们可以自由访问网络并执行任何待定作业和同步。 如果设备长时间处于空闲状态,系统将按每天大约一次的频率允许空闲应用访问网络。
具有前台服务(Foreground Service,通过startForeground启动的service)的应用,将不会进入待机模式。
可以看出,低电耗模式(Doze)是系统级别的,应用待机模式(App Standby)是应用级别的。
Doze和App Standby的区别:
Doze模式需要屏幕关闭(通常晚上睡觉或长时间屏幕关闭才会进入),而App Standby不需要屏幕关闭,App进入后台一段时间也会受到连接网络等限制。
Wake Lock 唤醒锁
不操作android设备一段时间后,Android设备就会进入休眠模式,Android系统的休眠分为浅度休眠和深度休眠。
首先进入的是浅度休眠,在这种模式下,lcd、tp等关闭用以节省电量。
一段时间后,若没有应用持有wake_lock的锁,进入深度睡眠模式,在深度休眠的过程中系统会首先冻结所有可以冻结的进程,然后依次挂起所有设备的电源,挂起顺序与设备注册的顺序相反,这样保证了设备之间电源的依赖性;直至最后进入省电模式,等待用户或者RTC唤醒;在唤醒过程中则会按照设备注册的顺序依次恢复每个设备的电源进入正常工作状态,解冻相关的进程,然后再进行浅度休眠的唤醒流程。
在深度睡眠模式下,是可以有消息push的,因为深度休眠下虽然AP会休眠,网络断开,但是BP是工作的,可以通过心跳机制,保持和服务器的长连接,当有消息来的时候,BP唤醒AP执行相应的操作。这里设置心跳机制应该是基于AlarmManager的,若是Timer则必须持有wakelock锁,这样会导致系统无法进入深度休眠,Alarm定时器是基于工作在BP的。
doze模式是不管你会不会持有wake_lock锁,只根据时间和传感器判断是否进入doze模式。在进入Doze模式之后,只有在白名单里面的应用可以正常使用,其他应用的网络,alarm都是被暂停的。
参考链接:
Android 的 doze mode 严重影响接收推送消息。 - V2EX
Android M新特性Doze and App Standby模式详解 - 知乎 (zhihu.com)
Android-电池优化Doze和Standby模式-AlarmManager失效_lioil.win的博客-CSDN博客
Android系统休眠机制和doze模式的关系_exstar的博客-CSDN博客
安卓 省电模式、低电耗(Doze)模式、应用待机(standby)模式、唤醒锁_android standby_神秘_博士的博客-CSDN博客