什么是IntentService?
IntentService是Service类的子类,所以说它就是一个Service,那么它与普通的Service有什么不同呢?我们知道Service是在应用的主线程里执行任务的,如果需要执行耗时任务,则需要新建一个子线程,而IntentService就直接为我们创建了子线程执行耗时任务。
IntentService在它的onCreate()函数中通过实例化了一个HandlerThread开启一个线程来处理所有Intent请求对象所对应的任务。IntentService在处理任务时,还是采用的Handler+Message的方式,创建一个名叫ServiceHandler的Handler对象,并把它直接绑定到HandlerThread所对应的子线程。 ServiceHandler把处理intent所对应的任务都封装到onHandleIntent的虚函数里;因此如果我们需要处理自己的任务,直接实现onHandleIntent方法,再在里面根据Intent的不同进行不同的处理就可以了。
好处
我们使用Service的时候一般是通过new一个Thread的方式去开启一个新的线程执行耗时任务,有了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);
}
}
这里面有一个Looper对象,用来在新的线程中启动一个消息循环,来检查是否有新的任务需要执行,ServiceHander最终会与这个Looper绑定,通过这个Handler向Looper发送消息。
下面是onCreate()的源码:
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
IntentService创建时就会创建并启动Handler线程(HandlerThread),然后再将Handler对象与这个线程的Looper对象绑定。
在IntentService的startCommand()方法中直接调用了onStart(),我们直接看onStart()的源码:
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
当你调用startService的时候,就会产生一条附带startId和Intent的Message并发送到MessageQueue中,接下来Looper发现MessageQueue中有Message的时候,就会通知Handler调用handleMessage()处理消息,代码如下
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
handleMessage()中调用了 onHandleIntent((Intent)msg.obj),这是一个抽象的方法,我们需要重写这个方法,在方法中处理我们的任务。当任务完成时就会调用stopSelf()结束这个Service。
结论
这是一个基于消息循环的服务,每次启动该服务并不是马上处理你的任务,而是首先会创建新的线程和对应的Looper,Handler,并且在MessageQueue中添加Message对象,当Looper发现有Message的时候调用Handler的handleMessage()方法,然后在onHandleIntent((Intent)msg.obj)中调用你的处理程序。处理完后即会停止自己的服务。
我们发现它是有一个问题的,所有请求的处理都是在同一个工作线程中完成,它们会顺序的一个一个执行(但不会阻塞主线程的执行),而不能并行完成。
。
例子
实现一个IntentSercie:
public class MyIntentService extends IntentService {
final static String TAG="vic";
public MyIntentService() {
super("");
}
@Override
protected void onHandleIntent(Intent arg0) {
Log.i(TAG,"begin onHandleIntent()");
try {
Thread.sleep(5*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG,"end onHandleIntent()");
}
}
启动这个IntentService的代码:
Intent intent=new Intent(this,MyIntentService.class);
startService(intent);