在之前的文章中,介绍了Android的四大组件之一Service。但是里边没有介绍到IntentService,今天介绍一下IntentService的使用和与Service的区别以及其源码分析。
我们知道Service虽然叫做服务,但是仍然运行在主线程的,也就是UI线程,那么在Service中肯定不能有耗时操作。那如果在Service中需要做耗时操作怎么办呢?那只能在Service中创建一个工作线程来做耗时操作了,而IntentService就是帮我们做了这件事。
IntentService简单使用
使用IntentService是非常简单的,只要集成IntentService并且重写onHandleIntent()就可以了,然后在onHandleIntent中做耗时操作。
IntentService源码分析
我们先看下IntentService的构造方法
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
首先,启动了一个HandlerThread,我们点进去看看HandlerThread,可以看到继承了Thread,说明这是一个Thread,Thread最主要就是run方法了。
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
可以看出来HandlerThread就是为该线程创建并启动了一个Looper,所以我一直觉得HandlerThread应该叫LooperThread,感觉这样更容易理解。
再回到IntentService的构造方法中,首先启动一个带Looper的线程,然后再通过子线程的Looper创建一个ServiceHandler。
再看下onStart方法,通过ServiceHandler将intent从主线程发送到工作线程。
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);
}
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
因为ServiceHandler持有的是子线程的Looper,所以handlerMessage也就是在子线程中执行的了。并且,在handleMessage中还调用了stopSelf。
所以使用IntentService主要有两个优点:
- 帮我们创建了Thread。
- 耗时操作完成之后,Service可以自杀。
IntentService本身源码很少,看起来很简单,但是涉及到很多基础知识,Handler、Looper、MessageQueue、ThreadLocal。所以IntentService成了面试必问了。
网友评论