前言:这次我们来看下安卓为我们封装的IntentService,它有以下特点:
- 它本质是一种特殊的Service,继承自Service并且本身就是一个抽象类
- 它可以用于在后台执行耗时的异步任务,当任务完成后会自动停止
- 它拥有较高的优先级,不易被系统杀死(继承自Service的缘故),因此比较适合执行一些高优先级的异步任务
- 它内部通过HandlerThread和Handler实现异步操作
- 创建IntentService时,只需实现onHandleIntent和构造方法,onHandleIntent为异步方法,可以执行耗时操作
一、IntentService的常规使用套路
public class MyIntentService extends IntentService {
public MyIntentService(){
super("MyIntentService");
}
/**
* 实现异步任务的方法
* @param intent Activity传递过来的Intent,数据封装在intent中
*/
@Override
protected void onHandleIntent(Intent intent) {
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
二、IntentService源码解析
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
public IntentService(String name) {
super();
mName = name;
}
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@WorkerThread
protected abstract void onHandleIntent(Intent intent);
}
- 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
- 65
- 66
先看看构造方法
public IntentService(String name) {
super();
mName = name;
}
- 1
- 2
- 3
- 4
这里是传入IntentService的名称,没什么其他操作,我们继续看
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
onCreate()方法调用了HandlerThread,并且start了它,并把HandlerThread的Looper对象传给了mServiceLooper这个Looper对象;并且创建了一个ServiceHandler类,传入mServiceLooper进去;所以我们要继续看看ServiceHandler这个类怎么定义的
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
我们发现ServiceHandler是继承Handler的,通过这个类来实现异步操作任务,重写handleMessage方法,里面调用了onHandleIntent方法,传入了msg.obj,说明具体UI操作在onHandleIntent方法里面定义,我们先看看这个方法怎么定义的
@WorkerThread
protected abstract void onHandleIntent(Intent intent);
- 1
- 2
这个onHandleIntent是一个抽象方法,要我们具体去实现,那么消息从哪来发送呢?别忘了IntentService类继承Service,开启服务会调用onStartCommand方法,我们看下这个方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
- 1
- 2
- 3
- 4
- 5
- 6
我们接着看看onStart方法
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
我们发现在开启服务时,最终会调用onStart里的Message类发送消息,进行异步操作,ServiceHandler接收Message类发送的消息后,在onHandleIntent让用户自行实现具体UI操作,实现异步任务的完成。
最后我们看看IntentService怎么自动结束Service服务,我们看看之前没有看的stopSelf(msg.arg1)方法。这里采用stopSelf(int startId)而不是stopSelf()来停止服务,是因为stopSelf()会立即停止服务,而stopSelf(int startId)会等待所有消息都处理完后才终止服务。