
Android 11/R 废弃了
IntentService
本文我们一起来回顾它
IntentService
1 | public abstract class IntentService |
- 废弃原因 : IntentService受到Android 8.0(API级别26)施加的所有后台执行限制。
- 替代方案 : 当运行在 Android 8.0 或者更高的版本的时候考虑使用WorkManager或者JobIntentService , 利用jobs代替services
回顾
IntentService (API level 3 ~ API level R)基于Service,可根据需要处理异步请求(表示为Intent)。客户端通过调用Context.startService(Intent)()发送请求。服务根据需要启动,依次使用工作线程处理每一个Intent,当它运行完成自动会停止。
这种“工作队列处理器”模式通常用于从应用程序的主线程分担任务。IntentService类存在是为了简化此模式并注意机制。要使用它,继承IntentService 并实现 onHandleIntent(android.content.Intent)。IntentService将收到Intents,启动一个工作线程,并适当停止服务
所有的请求都在一个单独的工作线程种处理 – 它们或许会耗费大量时间(并且不会阻塞应用程序的主循环),但是一次只处理一个请求。
构造函数 | 说明 |
---|---|
IntentService(String name) | 创建一个IntentService,由您的子类的构造函数调用 |
方法 | 说明 |
---|---|
onBind (Intent) | 除非您为服务提供绑定,否则不需要实现此方法,因为默认实现返回null |
onCreate() | 首次创建服务时由系统调用。不要直接调用此方法 |
onDestroy() | 由系统调用以通知服务该服务已不再使用且已被删除 |
onStart (Intent, int) | 改为实现 onStartCommand(Intent,int,int) |
onStartCommand(Intent,int,int) | 您不应为IntentService覆盖此方法。而是改写onHandleIntent(Intent),当IntentService收到启动请求时,系统将调用该方法。 |
setIntentRedelivery(boolean) | 设置Intent重新交付首选项 |
onHandleIntent(Intent) | 在工作线程上调用此方法以进行处理。 |
示例说明
- 一个进度条:更新加载进度
- 三个文本:服务状态(进行中/结束)、 进程状态(进行中/结束)和进度条百分比 (0-100%)
- 两个按钮:开始、停止
Activity 启动/停止任务、广播监听更新UI :文本状态和进度条进度
以下分别通过 IntentService、JobIntentService、WorkManager 3 种方式来实现进度加载效果
[ activity_main.xml ]
1 |
|
[ MainActivity.kt ]
1 | package com.shoewann.androidrtest |
1. IntentService 方式
[ MyIntentService.kt ]
1 | package com.shoewann.androidrtest |
1 | <service |
2. JobIntentService 方式
[ MyJobIntentService.kt ]
1 | package com.shoewann.androidrtest |
[ AndroidManifest.xml ]
1 | <uses-permission android:name="android.permission.WAKE_LOCK" /> |
2. WorkManager 方式
[ MyWorkManager.kt ]
1 | package com.shoewann.androidrtest |
[ app -> build.gradle ]
1 | dependencies { |
效果
1. IntentService
- 点击[开始],服务运行,线程计数完成后,服务和线程都结束。
- 点击[开始],服务运行,线程计数完成前,点击[停止],服务结束,线程计数完成后线程结束。
- 点击两次[开始],服务运行,第一次线程计数完成后,进行第二次线程计数,两次完成后,服务和线程都结束。
- 点击两次[开始],服务运行,第一次线程计数完成前,点击两次[停止],服务结束,第一次线程计数完成后线程结束,不进行第二次线程计数
2. JobIntentService
- 点击[开始],服务运行,线程计数完成后,服务和线程都结束。
- 点击[开始],服务运行,线程计数完成前,点击[停止],服务运行中,线程计数完成后线程结束。
- 点击两次[开始],服务运行,第一次线程计数完成后,进行第二次线程计数,两次完成后,服务和线程都结束。
- 点击两次[开始],服务运行,第一次线程计数完成前,点击两次[停止],服务运行中,第一次线程计数完成后线程结束,不进行第二次线程计数
3. WorkManager (OneTimeWork,非周期性)
- 点击[开始],服务运行,线程计数完成后,服务和线程都结束。
- 点击[开始],服务运行,线程计数完成前,点击[停止],服务无法结束,线程计数完成后线程结束。
- 点击两次[开始],服务运行,两次线程同时进行叠加计数,线程结束,服务运行中。
- 点击两次[开始],服务运行,两次线程同时进行叠加计数,点击两次[停止],两次完成后分别进行两次线程结束,服务运行中。
总结
IntentService 和 JobIntentService(都继承自Service),创建一个工作线程处理多线程任务,线程优先级相对普通线程要高,不需要手动结束,在任务处理完后,会自动关闭服务
IntentService从未被设计为可以取消的,因此缺少用于取消JobIntentService的任何API。因此,JobIntenService仅应用于不需要取消的工作。JobIntentService是作为实现的IntentService。尽管您可以stopService()用来销毁IntentService,这可能不会对用于onHandleIntent()的后台线程产生影响,在onHandleIntent方法完成前一个请求之前,它不会通过某些intent操作停止或处理任何其他请求。在任务执行完毕之前,将不会调用stopService()( via : how-to-cancel-a-jobintentservice )
WorkManager,并不是所有的任务都可以取消,当任务正在执行时是不能取消的,当然任务执行完成了,取消也是意义的,也就是说当任务加入到ManagerWork的队列中但是还没有执行时才可以取消。
- 如果将[开始]按钮里面的代码延时(70s)启动,模拟后台启动,
MainActivity.kt
改成如下:
1 | R.id.btnStart -> { |
再点击 开始 按钮之后,按Home键回到launcherIntentService 的方式会因为Android O / 8.0 后台限制抛出异常
1 | 2020-03-10 17:23:01.132 10813-10813/com.shoewann.androidrtest D/MainActivity: startIntentService() called |
其他均验证通过
JobIntentService 和 WorkManager 的方式为 IntentService 替代方案
以上就是本文的全部内容,其他方面请自行总结扩展测试,感谢您的阅读
本文基于Android 11 / R DP1 发布,如有不足, 欢迎指正