Source code of IntentService and HandlerThread, handlerthread
In this article, I will introduce IntentService in Android. when analyzing the principle of IntentService, I will analyze HandlerThread used in IntentService by the way.
IntentService
IntentService inherits from the services of four Android components. The difference between IntentService and Service is that it canProcess asynchronous requests, We all knowThe code in the Service is run in the main thread by default.If you directly process time-consuming tasks in the Service, it is easy to see ANR, while IntentService works directly in the Child thread. In addition, when we start IntentService using the startService (Intent) method, IntentService will process each Intent in the work thread, andStop yourself after completing these tasks.
Before analyzing the source code, let's take a look at how to use IntentService:
Public class MyIntentService extends IntentService {public MyIntentService () {super ("MyIntentService"); // The constructors with parameters of the parent class must be called.} @ Override protected void onHandleIntent (Intent intent) {// print the name of the current thread to prove that it is a Log in the Child thread. d ("MyIntentService", "Thread id is" + Thread. currentThread (). getName () ;}@ Override public void onDestroy () {super. onDestroy (); // to prove that IntentService stops its own Log after processing the work. d ("MyIntentService", "onDestroy ");}}
It can be seen that using IntentService is really very simple. We only need to inherit IntentService and provide a constructor, And the constructors of the parent class must be called internally, then rewrite the onHandleIntent (Intent intent) method to process specific business logic in the onHandleIntent method, and do not worry about ANR, because this method is already running in the Child thread.
Next, let's take a look at the source code of IntentService:
Public class IntentService extends Service {private volatile low.mserviceloader; private volatile ServiceHandler mServiceHandler; private String mName; private final class ServiceHandler extends Handler {public ServiceHandler (Looper) {super (looper );} @ Override public void handleMessage (Message msg) {onHandleIntent (Intent) msg. obj); stopSelf (msg. arg1) ;}@ WorkerThread protected abstract void onHandleIntent (@ Nullable Intent intent);/*** Creates an IntentService. invoked by your subclass's constructor. ** @ param name Used to name the worker thread, important only for debugging. */public IntentService (String name) {super (); mName = name ;}@ Override public void onCreate () {super. onCreate (); // create a HandlerThread object HandlerThread thread = new HandlerThread ("IntentService [" + mName + "]"); thread. start (); // call the start () method to enable the thread after the HandlerThread object is created. // obtain the low.mserviceloaders = thread created in HandlerThread. getLooper (); // use this logoff to create a Handler mServiceHandler = new ServiceHandler (mserviceloader) ;}@ Override public void onStart (@ Nullable Intent intent, int startId) {Message msg = mServiceHandler. obtainMessage (); msg. arg1 = startId; msg. obj = intent; mServiceHandler. sendMessage (msg) ;}@ Override public void onDestroy () {mserviceloading. quit ();}}
From the source code, we can see thatMyIntentServiceThe constructor must call the parameter constructor of the parent class because IntentService needs to name its worker thread for debugging. This code can be confirmed in the onCreate () method:
HandlerThread thread = new HandlerThread ("IntentService [" + mName + "]"); // mName is the parameter passed in the constructor.
When IntentService is started using the startService (Context, Intent) method, the onCreate and onStart methods of IntentService are called back:
1. Create a HandlerThread in the onCreate () method of the callback, enable this thread, obtain the logoff created in HandlerThread, and create a ServiceHandler using this logoff.
2. The onStart (@ Nullable Intent intent, int startId) method will be called back. We can see that in the onStart method, a Message will be obtained through ServiceHandler, and make the Message carry our request parameters, and then send the Message through ServiceHandler.
3. The Message sent by ServiceHandler will be distributed to the internal ServiceHandler handleMessage (Message msg) method of IntentService. Here the abstract method onHandleIntent (@ Nullable Intent intent) of IntentService will be called, and there is an annotation on this method:@ WorkerThreadThis method is called in the work thread. Then the stopSelf method of the Service is called to stop the Service. Therefore, you do not need to call the stopSelf method.
4. Once IntentService calls the stopSelf method, the onDestroy () method will be called back. The logoff created in HandlerThread will exit the loop.
Note the following when using IntentService:
1. When using IntentService, do not override the onStartCommand method. Instead, rewrite the onHandleIntent method. When IntentService is started, the onHandleIntent method is called back by the system.
2. do not provide the onBind method of Service in your IntentService. You do not need to implement this method because IntentService implements this method by default and returns null.
HandlerThread
HandlerThread is a class widely used in Android. It inherits from Thread and is used to start a new Thread with built-in logoff. The logoff created in this new Thread can be used to create the Handler class, therefore, HandlerThread is often used with Handler, which is also the reason why the class name is HandlerThread.