最近看Android基础,看过了Handler源码以及对应的HandlerThread,包括涉及到的ThreadLocal类,觉得很有意思。这几个类网上的源码分析比较多,也算是比较经典的Android源码,我就不分析了。这篇要记录的是另一个组件IntentService的源码相关,源码不多但是很有意思。
基本概念 IntentService应该属于那种用过的人很熟,没用过的人没听过的组件。源码的注释是这样的:
IntentService is a base class for {@link Service}s that handle asynchronous requests (expressed as {@link Intent}s) on demand.  Clients send requests through {@link android.content.Context#startService(Intent)} calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.
 
简单的说,就是对于一般的Service来说,无论我们是start还是bind,都要自己管理Service的销毁。而IntentService呢,你可以把耗时操作扔给它,然后就不用管了,它自己处理完了以后就把自己关掉了。
源码分析 IntentService的源码太少了,我直接就把整个类copy了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 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);         }     }     public  IntentService (String name)           super ();         mName = name;     }     public  void  setIntentRedelivery (boolean  enabled)           mRedelivery = enabled;     }     @Override      public  void  onCreate ()           super .onCreate();         HandlerThread thread = new  HandlerThread("IntentService["  + mName + "]" );         thread.start();         mServiceLooper = thread.getLooper();         mServiceHandler = new  ServiceHandler(mServiceLooper);     }     @Override      public  void  onStart (@Nullable Intent intent, int  startId)           Message msg = mServiceHandler.obtainMessage();         msg.arg1 = startId;         msg.obj = intent;         mServiceHandler.sendMessage(msg);     }     @Override      public  int  onStartCommand (@Nullable Intent intent, int  flags, int  startId)           onStart(intent, startId);         return  mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;     }     @Override      public  void  onDestroy ()           mServiceLooper.quit();     }     @Override      @Nullable      public  IBinder onBind (Intent intent)           return  null ;     }     @WorkerThread      protected  abstract  void  onHandleIntent (@Nullable Intent intent)  } 
源码很少。首先这是一个抽象类,继承自Service,继承这个类的话必须实现onHandleIntent这个方法,也是在这个方法里我们进行耗时操作。
首先我们看onCreate方法,也是Service的生命周期毁掉方法,在这里首先会new一个HandlerThread出来,然后拿到这个HandlerThread线程对应的Looper,并使用这个Looper构建了一个ServiceHandler出来。ServiceHandler继承自Handler。在onStart方法里面,其实就是我们常用的用ServiceHandler发送了一个Message出去,在handleMessage方法这里会调用我们刚才说到的onHandleIntent方法,这个方法执行完毕以后接着调用stopSelf方法关掉自己。接着在onDestroy方法里会调用Looper.quit方法跳出Looper的循环。
逻辑很简单,我之所以觉得有意思的是Google的工程师真的是把自己写的组件用的淋漓尽致,看起来挺有用的IntentService,其实本质上就是利用了HandlerThread自己能够提供线程对应的Looper的特性,实现了一个IntentService-HandlerThread-Handler的绑定。用最简单易懂的代码实现了一个异步耗时任务的Service。
既然分析到这里,那么正好也分析一下HandlerThread的这个特性,源码仍然不多:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 public  class  HandlerThread  extends  Thread      int  mPriority;     int  mTid = -1 ;     Looper mLooper;     public  HandlerThread (String name)           super (name);         mPriority = Process.THREAD_PRIORITY_DEFAULT;     }     public  HandlerThread (String name, int  priority)           super (name);         mPriority = priority;     }     protected  void  onLooperPrepared ()       }     @Override      public  void  run ()           mTid = Process.myTid();         Looper.prepare();         synchronized  (this ) {             mLooper = Looper.myLooper();             notifyAll();         }         Process.setThreadPriority(mPriority);         onLooperPrepared();         Looper.loop();         mTid = -1 ;     }     public  Looper getLooper ()           if  (!isAlive()) {             return  null ;         }         synchronized  (this ) {             while  (isAlive() && mLooper == null ) {                 try  {                     wait();                 } catch  (InterruptedException e) {                 }             }         }         return  mLooper;     }     public  boolean  quit ()           Looper looper = getLooper();         if  (looper != null ) {             looper.quit();             return  true ;         }         return  false ;     }     public  boolean  quitSafely ()           Looper looper = getLooper();         if  (looper != null ) {             looper.quitSafely();             return  true ;         }         return  false ;     }     public  int  getThreadId ()           return  mTid;     } } 
核心代码都在run方法里面了。其实就做了三件事情(假设看到这里的同学都熟悉Looper的源码了),Looper.prepare()、mLooper = Looper.myLooper()和Looper.loop()。熟悉Looper的同学肯定已经了解了,因为我们在任何地方想要自己实现一个子线程的Handler,都需要手动调用Looper.prepare()和Looper.loop()。官方提供的这个HandlerThread其实就是帮我们做了这个事情,然后再对外暴露一个getLooper()方法,你就可以拿到这个线程对应的Looper来构建对应的Handler。IntentService也是利用了这一点,充分精简了代码。
总结 IntentService与其说是官方提供的一个组件,不如说是HandlerThread的一个最佳实践。他们的源码都没有什么深度,跟Handler相关的几个类都差很远,但是给我们提供的编码思路却是很有用的。