Android应用实现用户在线时全程不中断常驻线程的方案咨询
可靠的主流实现方案
你原有基于Service承载任务的思路方向是对的,但原生普通Service在高版本Android上有很大概率被系统回收,结合当前Android官方推荐的实现规范,根据你的需求可以选择以下适配方案:
注:原有方案的核心缺陷:Android 8.0及以上系统对后台隐式Service做了严格的回收策略,应用退到后台2分钟左右就会被系统强制杀死;其次Service默认运行在主线程,内部启动的子线程如果没有做异常兜底,崩溃后不会自动恢复。
方案1:仅应用在前台使用时需要执行任务(用户正在交互)
如果你的任务只需要在App处于前台时执行,优先采用前台Service + ScheduledExecutorService的组合:
- 启动Service后在
onCreate回调中调用startForeground()弹出前台通知,Android 8.0及以上需要提前创建对应的通知渠道,标记为前台服务的Service优先级和前台Activity一致,几乎不会被系统回收 - 用
ScheduledExecutorService实现1分钟间隔的定时任务,比普通Thread+Handler实现的定时逻辑更稳定,自带线程池管理和异常捕获能力,单个任务崩溃不会影响整个定时逻辑 - 启动时机依然放在自定义Application的
onCreate方法中,注意增加主进程判断,避免多进程场景下重复启动服务执行重复任务
方案2:应用退到后台也需要保证任务执行
如果你的任务需要在App退到后台甚至被杀死后依然能执行,根据对实时性的要求选择不同方案:
- 对实时性要求高(必须每分钟上报):在前台Service的基础上增加保活逻辑,比如1像素悬浮窗保活、JobScheduler定时拉活,但要注意应用市场的审核规则,非合理的后台保活行为会被Google Play等应用商店下架
- 对实时性要求不高(允许上报延迟):优先用Room数据库做本地数据缓存,再用
WorkManager实现定期批量上报,该方案是官方首推的通用后台任务实现,兼容API 14及以上所有系统版本,系统会自动选择最优的执行方式,就算应用被杀死也会在合适的时机自动恢复执行,不会丢失数据,比实时上报更省电。注意WorkManager的最小执行间隔是15分钟,无法满足1分钟的实时上报要求。
通用优化建议
- 不要直接在定时任务线程中做跨进程的数据库写入操作,先把要上报的数据缓存在本地,任务触发时再统一读取上报,避免长时间持有数据库连接导致内存泄漏
- 任务执行前增加网络状态判断,无网络时直接缓存数据不上报,减少无效请求
- 不要用静态变量持有线程、Service或者Context实例,避免出现内存泄漏
内容的提问来源于stack exchange,提问作者tyoma
相关产品推荐
相关产品推荐

