Android 锁屏后Socket长连接踩坑总结

最近项目中遇到手机休眠后Socket心跳发不出去的问题,折腾许久终于解决,所以做个记录。

每种手机都有自己的休眠策略,Android手机在长时间不操作时会自动让CPU进入睡眠状态,这就导致除AlarmManager外,Android Timer / Handler / Thread.sleep()这些方式实现的定时任务都无法正常运行。

在安卓6.0之后,谷歌又加入了全新的Doze模式,就是说当屏幕关闭一段时间后,系统会对CPU,网络、Alarm等活动做出限制,从而延长电池寿命
但是系统会间歇性退出Doze模式一小段时间,让应用完成他们的同步操作和Alerm任务。

Android应用处于Doze模式下时会受到以下限制:
1.网络访问被挂起
2.Wake Locks被无视
3.AlarmManager创建的Alarms将被推迟到下一个维护窗口,通过setAndAllowWhileIdle()以及setExactAndAllowWhileIdle()设置的Alarms将会在Doze模式下正常执行,同时通过setAlarmClock()设置的Alarms也会正常执行---Android系统将会在设定时间之前自动退出Doze模式
4.Android系统将会停止执行Wi-Fi的扫描
5.Android系统将会停止Sync Adapter的同步操作
6.Android系统也会停止JobScheduler的定时操作

详细请参考:Android开发技巧(三)—— 创建定时任务https://blog.csdn.net/qq_41205771/article/details/104446141

Doze模式:

Android的Doze模式https://www.jianshu.com/p/d39ac63b445b

所以,要实现手机休眠后Socket正常发送心跳,目前有三种方案:

1.采用AlarmManager进行定时

setAndAllowWhileIdle()以及setExactAndAllowWhileIdle()设置的Alarms在Doze模式仍然能够正常执行,并且执行时能够自动唤醒CPU。采用AlarmManager进行定时,到达设定的心跳发送时间后,AlarmManager可以唤醒CPU完成心跳发送的操作。但是经过OPPO HUAWEI等国内厂商实测发现,AlarmManager最短定时时间为5分钟,小于五分钟的定时任务,休眠之后一律会延迟到五分钟在执行。所以此种方式只适合心跳时间大于5分钟的场景,我们项目心跳时间最长为2分钟,所以未采用此方案。

详细测试结果参考:

Android Doze模式适配实验记录https://blog.csdn.net/gaoxiaoweiandy/article/details/95778748?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~default-3.queryctr&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~default-3.queryctr&utm_relevant_index=6AlarmManager使用请参考:

定时任务AlarmManager的使用注意事项https://blog.csdn.net/sp_wei/article/details/83146655

2.添加白名单

添加Doze白名单后,应用不受Doze的影响,即Doze不会对该应用进行限制,如该应用的Job、Alarm、网络等不会进行限制。不过除了Android的Doze白名单,各厂商基本也都有自己的白名单,俩个都需要添加,否则不起作用。

Android 8.1 Doze模式分析(五) Doze白名单及Debug方式https://blog.csdn.net/FightFightFight/article/details/81392488

Doze白名单添加参考:

Doze和App Standby模式下的Android应用适配https://www.jianshu.com/p/f044ce3f5913

各厂商白名单基本在设置->电池->电池优化,需要引导用户手动设置。

查看Doze白名单命令:

adb shell dumpsys deviceidle whitelist

3.WakeLock唤醒锁+Doze白名单方式

唤醒锁使用请参考:

Android中的WakeLock使用https://blog.csdn.net/u012398902/article/details/52838386

持有唤醒锁的应用,锁未释放之前,CPU不会进行休眠。此方式需同时添加Doze白名单和各厂商电池优化白名单,不在Doze白名单的应用,持有的唤醒锁会被无视。不添加各厂商电池优化白名单,实测还是会休眠。

查看Android WakeLock唤醒锁持有列表命令:

adb shell dumpsys "power|grep -i wake"

后记:笔者采用了第三种方案,实测唤醒锁有时会失效,打算同时使用AlarmManager,休眠时定时检测唤醒锁状态,待测试效果。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值