IntentService源码分析

来源:互联网 发布:mac windows7 iso下载 编辑:程序博客网 时间:2024/06/05 21:14

什么是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);
0 0