[TOC]

文章参考:https://blog.csdn.net/SuperBigLw/article/details/53126101

一:概述

很多时候,我们开启一个Service是想执行一个耗时任务。初学者可能直接就在Service里面执行耗时任务。这是非常不可取的。不管是何种Service,它默认都是在应用程序的主线程(亦即UI线程)中运行的。所以,如果你的Service将要运行非常耗时或者可能被阻塞的操作时,你的应用程序将会被挂起,甚至会出现ANR错误。为了避免这一问题,你应该在Service中重新启动一个新的线程来进行这些操作。现有两种方法大家参考:

1、 直接在Service的onStartCommand()方法中新建一个线程来执行;

2、Android SDK 中为我们提供了一个现成的Service类来实现这个功能,它就是IntentService,它主要负责以下几个方面:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Creates a default worker thread that executes all intents delivered to onStartCommand() separate from your application's main thread.
// 生成一个默认的且与主线程互相独立的工作者线程来执行所有传送至 onStartCommand() 方法的Intetnt


Creates a work queue that passes one intent at a time to your onHandleIntent() implementation, so you never have to worry about multi-threading.
//生成一个工作队列来传送Intent对象给你的onHandleIntent()方法,同一时刻只传送一个Intent对象,这样一来,你就不必担心多线程的问题。

Stops the service after all start requests have been handled, so you never have to call stopSelf().

// 在所有的请求(Intent)都被执行完以后会自动停止服务,所以,你不需要自己去调用stopSelf()方法来停止该服务

Provides default implementation of onBind() that returns null.

提供了一个onBind()方法的默认实现,它返回null

Provides a default implementation of onStartCommand() that sends the intent to the work queue and then to your onHandleIntent() implementation

// 提供了一个onStartCommand()方法的默认实现,它将Intent先传送至工作队列,然后从工作队列中每次取出一个传送至onHandleIntent()方法,在该方法中对Intent对相应的处理;


二、使用方法

IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在同一个单独的worker thread中处理,不会阻塞应用程序的主线程。
这里就给我们提供了一个思路,如果有耗时的操作可以在Service里面开启新线程,也可以使用IntentService来处理耗时操作。 但你若是想在Service中让多个线程并发的话,就得使用第一种方法,在Service内部起多个线程,但是这样的话,你可要处理好线程的同步。

也就是说,如果只是需要有一个线程的话那么我们使用IntentService是很方便的,如果需要处理多个线程并发的话那只能使用第一种方法。

三、创建IntentService

1、以Android Studio为环境,非常的方便
image

可以将这个勾选取消
image

这样会自动生成一个IntentService,但是你发现整个代码很乱,你可以把这些去掉只留下关键的方法就可以,我只留下了构造方法和onHandleIntent方法。

2.修改代码,在onHandleIntent方法种实现业务方法,例如

1
2
3
4
5
6
7
8
9
10
11
12
protected void onHandleIntent(Intent intent) {
Log.e(TAG, intent.getStringExtra("info"));

for(int i = 0;i<20;i++){
Log.e(TAG, "onHandleIntent-" + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

3.在Mainactivity种修改

1
2
3
Intent intent = new Intent(this, MyIntentService.class);
intent.putExtra("info", "传递数据");
startService(intent);

4.当IntentService全部执行完后将自动停止
image

可以看出在启动这个intentService后再次点击则会在上个耗时操作完成后继续执行(队列的方式),并且在所有操作执行后自动销毁。并且不会阻塞主线程
通常使用该IntentService完成本App内部的耗时操作
至此IntentService的基本使用方法就结束了十分的简单实用