Android 后台任务处理指南
0x00 后台任务处理指南
Android的主线程(MainThread)主要是处理UI和绘制,接收用户的交互以及处理生命周期等事件。在UI线程中处理耗时操作,将严重影响用户的体验。因此很多任务是需要放在后台任务中进行处理的。
当需要后台任务时需要考虑以下因素:
- 任务是否可以延期执行,还是需要马上执行? 例如,当你点击页面上按钮去请求网络数据时,这个任务是需要立即执行,不应该让用户等待。如果是上传用户日志到服务器中,这个任务在不影响用户体验的情况下是可以推迟执行的。
- 任务一旦开启,操作系统是否要保持该任务所在的进程? 例如,解码一个
bitmap
并显示到屏幕上,这个任务是需要App
在前台并且该进程是活跃的。而一个音乐播放器在App
退到后台甚至用户没有进行操作时,也是需要保持播放服务能够正常的进行。 - 任务是否需要响应系统的触发事件?这些触发事件是指像网络、电量、空间存储等状态的变化。当这些状态变化的时候,可以触发任务的执行。例如当从飞行模式切换回来时,
App
能够自动与服务端通讯,而且如果此时进程已经被系统杀掉,那么该任务所在的进程应该在有网络的情况下重新创建,然后执行后台任务。
目前Android系统中处理后台任务的方式有以下几种:
- ThreadPools(线程池)
- Foreground Services(前台服务)
- WorkManager(任务管理器)
ThreadPools
当一个任务必须在App
处于前台状态时处理,可以使用ThreadPools
。如果要响应操作系统的触发事件状态,那么只能通过Broadcast Receiver
了。
Foregound Services
对于必须执行完成的,并需要马上执行的任务,可以使用Foreground Services
。前台服务会在通知栏中保持一个无法手动取消的通知,它会告诉操作系统这个任务非常重要,不要杀掉。
WorkManager
对于必须执行完成的,并能否延迟执行的任务,可以使用WorkManager
。任务管理器是一个Android
库,它优雅地实现了可延迟任务的执行,它还能够响应操作系统的触发事件(网络状态、电量变化等事件)。Android 6.0以上操作系统 WorkManager
使用了框架层中的JobScheduler
,用于优化电量消耗和批量任务的执行。在低于Android 6.0 (API 23)
的系统,如果项目有引用Firebase
相关依赖库的话, WorkManager
则会使用Firebase JobDispatcher
,否则WorkManager
使用AlarmManager
来优雅地处理后台任务。
因此WorkManager
其实是封装了JobScheduler
、Firebase JobDispatcher
和 AlarmManager
的调用逻辑。它能够以最优的方式选择处理后台任务的方式,这也是google
目前推荐处理后台任务的一种方式。
后台任务处理的限制
为了延长电量使用,在 App
处于后台不可见得情况下 Android 限制了后台任务的执行情况。
- Android 6.0 (API 23) 引入了 Doze mode and app standby(低耗电模式和待机模式)。在此模式下限制了
App
访问网络、工作任务和同步的操作。 - Android 7.0 (API 24) 限制了隐式广播
(limited implicit broadcasts)
并引入了 Doze-on-the-Go - Android 8.0 (API 26) 深度限制了后台任务行为limited background behavior,例如后台获取地理位置。
WorkManager
是处理以上限制的最好工具。
0x01 参考文档
https://developer.android.com/guide/background