0.前言
转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52440418
IntentService是一种特殊的Service,它继承了Service,因此它自然会比单纯的线程优先级要高,然后它自己依旧是一个抽象类,需要创建自己的子类。IntentService可用于执行后台耗时任务,执行完毕后会自动停止。这是它最大的特点。
IntentService内部封装了HandlerThread和Handler,因此仍然需要先从HandlerThread讲起。
1.HandlerThread
Android API提供了HandlerThread来创建线程。官网的解释是:
//Handy class for starting a new thread that has a looper. //The looper can then be used to create handler classes. //Note that start() must still be called.
(1)HandlerThread继承自Thread,实际上就一个Thread,只不过它比普通的Thread多了一个Looper,对外提供自己这个Looper对象的get方法,然后创建Handler时将HandlerThread中的looper对象传入。
(2)不要忘记创建HandlerThread时必须调用其start()方法。
(3)但是需要注意的是,当activity退出了,这个HandlerThread线程并没有终止,还是在那里做looper死循环,这样随着activity的创建和退出的次数增多,这样占用系统资源的无用线程会越来越多,因此在明确不需要使用HandlerThread时,可通过quit()或者quitSafely()来终止线程执行。如下所示。
mHandlerThread.getLooper().quit();
HandlerThread的简单使用实例:
/* *@author SEU_Calvin *@date 2016/09/05 */ HandlerThread handlerThread = new HandlerThread("新线程"); handlerThread.start(); //创建HandlerThread后一定要记得start() Handler handler = new Handler(handlerThread.getLooper()){ //重写handleMessage方法处理消息 //通过handler在外部send或者post消息,就会在子线程中处理该消息 @Override public void handleMessage(Message msg) { super.handleMessage(msg); //处理消息,执行耗时任务 } };
使用HandlerThread的好处:
(1)如果多次使用new Thread(){...}.start()这种方式开启一个子线程,会创建多个匿名线程,降低程序执行性能。而HandlerThread是Looper的,这样便可以通过消息来多次重复使用该线程,节省开支。
(2)HandlerThread是一个很有用的类,为IntentService的实现提供了技术基础。
2.IntentService
IntentService的简单使用实例:
/* *@author SEU_Calvin *@date 2016/09/05 */ public class MyIntentService extends IntentService { public MyIntentService () { super(“MyIntentService”); } @Override protected void onHandleIntent(Intent intent) { String action = intent.getStringExtra("action"); if ("com.seucalvin.action1".equals(action)) { //逻辑实现第一个耗时任务 }else if("com.seucalvin.action2".equals(action)){ //逻辑实现第二个耗时任务 } } @Override public void onDestroy() { //所有任务处理完自行结束,回调该方法 super.onDestroy(); } } //使用时 Intent intent = new Intent(this, MyIntentService.class); intent.purExtra("action", "com.seucalvin.action1"); startService(intent); //第一个任务 intent.purExtra("action", "com.seucalvin.action2"); startService(intent); //第二个任务
2.1 IntentService的onCreate()
上面也提到了,IntentService内部封装了HandlerThread和Handler。这个可以通过其onCreate方法源码得到验证。
public void onCreate(){ super.onCreate(); HandlerThread thread = new HandlerThread("IntentService ["+mName+"]"); thread.start(); mServiceHandler = new ServiceHandler(thread.getLooper()); }
从它的onCreate源码可以看出,IntentService第一次启动时,便创建了HandlerThread,并使用它的Looper来构造一个Handler对象mServiceHandler,这样的话,通过mServiceHandler发送的消息最终都会在HandlerThread中执行一些后台任务。
那么消息是从哪里发出来的呢?ServiceHandler又是如何处理消息的呢?
2.2 消息的发出
每次通过startService(Intentintent)启动IntentService,onStartCommand()都会调用一次处理这个Intent,onStartCommand()又调用了onStart()方法。其中便有消息发出的细节,实现如下:
public void onStart(Intent intent, int startId){ Message msg = mServiceHandler.obtainMessage(); msg.arg1 = started; msg.obg = intent; mServiceHandler.sendMessage(msg); }
2.3 消息的处理
消息处理肯定是在ServiceHandler中进行,那么我们来看一下ServiceHandler的源码:
private final class ServiceHandler extends Handler{ //获取HandlerThread的looper public ServiceHandler(Looper looper){ super(looper); } @override public void handleMessage(Message msg){ onHandleIntent((Intent)msg.obj); stopSelf(msg.arg1); } }
从ServiceHandler的源码可以看出,handleMessage处理消息会交给onHandleIntent()方法。通过startService(Intent intent)启动IntentService时的intent便传过来了。通过intent中的参数便可以在onHandleIntent()方法中开启不同的具体的后台任务。
那么onHandleIntent必然是抽象方法,需要我们在实例里具体实现处理逻辑。
最后通过stopSelf(int startId)来等待所有消息都处理完才停止服务(调用stopSelf()方法会立即停止服务),其中startId代表启动服务的次数,由系统生成,在其参数startId跟最后启动该service时生成的ID相等时才会执行停止服务。
总结一下,IntentService有以下特点:
(1)不需要调用stopSelft()主动结束服务。在所有的intent被处理完后,系统会自动关闭服务。
(2)多个后台任务同时存在时,因为Looper是顺序处理消息的,所以IntentService会按照发起任务顺序排队执行。
(3) 继承IntentService的类至少要实现其构造方法和onHandleIntent()方法。
至此关于HandlerThread以及IntentService的解析结束。
转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52440418