Android IntentService 使用
01.使用步骤
- 步骤1:定义IntentService的子类:传入线程名称、复写onHandleIntent()方法
- 步骤2:在Manifest.xml中注册服务
- 步骤3:在Activity中开启Service服务
02.具体案例
步骤1:定义IntentService的子类:传入线程名称、复写onHandleIntent()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64/**
* 初始化工作,子线程,处理耗时操作和避免在application做过多初始化工作,比如初始化数据库等等
*/
public class InitializeService extends IntentService {
private static final String ACTION_INIT = "initApplication";
public static void start(Context context , String name) {
Intent intent = new Intent(context, InitializeService.class);
intent.setAction(ACTION_INIT);
intent.putExtra("name",name);
context.startService(intent);
}
/**
* 在构造函数中传入线程名字
**/
public InitializeService(){
//调用父类的构造函数
//构造函数参数=工作线程的名字
super("InitializeService");
}
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
String name = intent.getStringExtra("name");
Log.e("IntentService初始化","onHandleIntent----"+name);
if (ACTION_INIT.equals(action)) {
initApplication();
}
}
}
public void onCreate() {
super.onCreate();
Log.e("IntentService初始化","onCreate");
}
private void initApplication() {
//处理耗时操作和避免在application做过多初始化工作,比如初始化数据库等等
Log.e("IntentService初始化","initApplication");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public int onStartCommand(int flags, int startId) { Intent intent,
Log.e("IntentService初始化","onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
public void onDestroy() {
super.onDestroy();
Log.e("IntentService销毁","onDestroy");
}
}步骤2:在Manifest.xml中注册服务
1
<service android:name=".InitializeService"/>
步骤3:在Activity中开启Service服务。
1
2
3//同一服务只会开启一个工作线程
//在onHandleIntent函数里依次处理intent请求。
InitializeService.start(this,"yc"+i);
03.打印日志
多次开启,打印日志如下
1
2
3
4
5
6
7
8
9
10
112019-05-23 11:57:51.032 20012-20012/cn.ycbjie.ycthreadpool E/IntentService初始化: onCreate
2019-05-23 11:57:51.033 20012-20012/cn.ycbjie.ycthreadpool E/IntentService初始化: onStartCommand
2019-05-23 11:57:51.034 20012-20356/cn.ycbjie.ycthreadpool E/IntentService初始化: onHandleIntent----yc8
2019-05-23 11:57:51.034 20012-20356/cn.ycbjie.ycthreadpool E/IntentService初始化: initApplication
2019-05-23 11:57:51.224 20012-20012/cn.ycbjie.ycthreadpool E/IntentService初始化: onStartCommand
2019-05-23 11:57:51.439 20012-20012/cn.ycbjie.ycthreadpool E/IntentService初始化: onStartCommand
2019-05-23 11:57:53.037 20012-20356/cn.ycbjie.ycthreadpool E/IntentService初始化: onHandleIntent----yc9
2019-05-23 11:57:53.037 20012-20356/cn.ycbjie.ycthreadpool E/IntentService初始化: initApplication
2019-05-23 11:57:55.041 20012-20356/cn.ycbjie.ycthreadpool E/IntentService初始化: onHandleIntent----yc10
2019-05-23 11:57:55.041 20012-20356/cn.ycbjie.ycthreadpool E/IntentService初始化: initApplication
2019-05-23 11:57:57.045 20012-20012/cn.ycbjie.ycthreadpool E/IntentService销毁: onDestroy如果启动IntentService多次,会出现什么情况呢?
- IntentService多次被启动,那么onCreate()方法只会调用一次,所以只会创建一个工作线程。但是会调用多次onStartCommand方法,只是把消息加入消息队列中等待执行
多次开启intentService,那为什么工作任务队列是顺序执行的?
- 结论:如果一个任务正在IntentService中执行,此时你再发送一个新的任务请求,这个新的任务会一直等待直到前面一个任务执行完毕才开始执行。
- 分析:
- 由于onCreate() 方法只会调用一次,所以只会创建一个工作线程;
- 当多次调用 startService(Intent) 时(onStartCommand也会调用多次)其实并不会创建新的工作线程,只是把消息加入消息队列中等待执行,所以,多次启动 IntentService 会按顺序执行事件
- 如果服务停止,会清除消息队列中的消息,后续的事件得不到执行。
04.IntentService作用
- IntentService的介绍
- IntentService是自己维护了一个线程,来执行耗时的操作,然后里面封装了HandlerThread,能够方便在子线程创建Handler。
- IntentService是继承自Service用来处理异步请求的一个基类,客户端startService发送请求,IntentService就被启动,然后会在一个工作线程中处理传递过来的Intent,当任务结束后就会自动停止服务。
- IntentService的作用
- 开启多线程
- 执行异步请求逻辑
- IntentService 有以下几个特性:
- IntentService 内部创建了一个工作线程,用于在子线程内执行传递给
onStartCommand()
的所有 Intent,开发者无须关心多线程问题 - IntentService 内部通过 HandlerThread 和 Handler 来实现异步操作
- IntentService 是以串行方式处理外部传递来的任务,即只有当上一个任务完成时,新的任务才会被执行
- 在处理完所有任务请求后会自动停止,因此不必手动调用
stopSelf()
方法 - 提供了
onBind()
的默认实现(返回 null) - IntentService 是四大组件之一,拥有较高的优先级,不易被系统杀死,因此适合于执行一些高优先级的异步任务
- IntentService 内部创建了一个工作线程,用于在子线程内执行传递给
05.IntentService使用场景
- IntentService不需要我们自己去关闭Service,它自己会在任务完成之后自行关闭,不过每次只能处理一个任务,所以不适用于高并发,适用于请求数较少的情况。
- 例如播放音乐、下载文件等,但 Service 默认是运行于 UI 线程的,如果想要依靠其来完成一些耗时任务,就需要自己来建立子线程,这相对比较繁琐,所以官方也为开发者提供了 IntentService 来解决这一问题
- 1.类似于APP的版本检测更新,后台定位功能以及读取少量的IO操作。
- 2.线程任务需按顺序、在后台执行,比如阿里云推送的服务service就是继承IntentSerVice
- 3.将部分application初始化的逻辑放到intentService里面处理,可以提高application启动时间
1 | 目前,由于正式项目中application初始化工作太多,所以决定分担部分逻辑到IntentService中处理 |