IntentService源码分析

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

你可能感兴趣的:(handler,service,IntentService)