The original model

We know that the Service runs in the main thread, so if we perform time-consuming code operations in the Service, we need to start a child thread to handle the code. For example, we can start child threads in the onStartCommand method to handle time-consuming code.

public int onStartCommand(Intent intent, int flags, int startId) {

         Thread thread = new Thread(){

            @Override

            public void run(a) {

                / * *

* Time-consuming code is written in child threads

* /


            }

          };

        thread.start();

        return super.onStartCommand(intent, flags, startId);

    }

Copy the code

However, as we all know, once a service is started, it runs forever and must be stopped by calling stopService() or stopSelf(). So, let’s modify the run method

public void run(a) {

         / * *

* Time-consuming code is written in child threads

* /


        stopSelf();



     }

    }

Copy the code

In this way, we can easily start a thread in the service and add stopSelf() at the end of the code; This allows the service to be terminated at the end of the code run. But is it a little bit of a hassle for us developers, it is a little bit of a hassle, like you sometimes forget to start the thread? Or forgot to call stopSelf()?

So, Google has given us a nice class that we don’t have to worry about all this stuff, because this class already does it for us to manipulate code in child threads. At the same time, when the child thread code completes, the service is automatically destroyed and no longer consumes memory resources. So, with this class, we don’t have to start the thread, and we don’t have to destroy the service. Because, this class takes care of it for us. This class is IntentService. The use of this class is similar to Service, but much easier and more convenient than Service. So let’s go straight to code, because I like to do it in code.

IntentService source

/ * *

* IntentService is a service that starts with {@linkService} is the base class to handle asynchronous requests

* The client sends the request through {@linkAndroid.content.context *#startService (Intent)}

* The service starts as needed, uses the worker thread to process each Intent thread in turn, and stops the service when the run job completes.

 *

* <p> This "work queue processor" mode is typically used to unload tasks

* Main thread from the application. The IntentService class exists in

* Simplify the schema and handle the mechanism. To use it, expand

* IntentService and implement {@link #onHandleIntent(Intent)}。 IntentService

Intents will be received, the worker thread will be started, and the service will be stopped

* right.

 *

* <p> All requests are processed on a worker thread - they can be

* As long as possible (and without blocking the application's main loop), but

* Only one request can be processed at a time.

 *

* /


public abstract class IntentService extends Service {



    // Start the thread Looper

    private volatile Looper mServiceLooper;

    // A handler for sending and processing messages

    private volatile ServiceHandler mServiceHandler;

    // Name of the child thread

    private String mName;

    // Whether it can be sent repeatedly

    private boolean mRedelivery;





    // Handle the message handler implementation

    private final class ServiceHandler extends Handler {

        public ServiceHandler(Looper looper) {

            super(looper);

        }



        @Override

        public void handleMessage(Message msg) {

            / / the child thread



            // Leave abstract methods to subclasses to override

            onHandleIntent((Intent)msg.obj);

            // Stop the service when the child task is finished

            stopSelf(msg.arg1);

        }

    }



    / * *

* Constructor

     * @paramName Worker Thread name useful for debugging

* /


    public IntentService(String name) {

        super(a);

        mName = name;

    }



    / * *

     * 

     * Sets intent redelivery preferences.  Usually called from the constructor

     * with your preferred semantics.

* Sets the intent replay preference, usually in the constructor call

     *

     *

* If set to true, {@link#onStartCommand(Intent, int, int)}@link Service#START_REDELIVER_INTENT}

Therefore, if the process dies before onHandleIntent returns, the process will be restarted and the intent will be sent

* If multiple intents are sent, only the most recent one will be guaranteed to be resent

     *

* If set to false, {@link#onStartCommand(Intent, int, int)}@link Service#START_NOT_STICKY}

* If the process dies, the intent is dead

     *

* /


    public void setIntentRedelivery(boolean enabled) {

        mRedelivery = enabled;

    }



    @Override

    public void onCreate(a) {



        super.onCreate();



        // Start a thread with HandlerThread and generate looper and message queue

        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");

        thread.start();



        // Get the looper of the above child thread

        mServiceLooper = thread.getLooper();

        // Initialize handler

        mServiceHandler = new ServiceHandler(mServiceLooper);

    }



    @Override

    public void onStart(Intent intent, int startId) {

        // Onstart sends a message to handle



        Message msg = mServiceHandler.obtainMessage();

        msg.arg1 = startId;

        msg.obj = intent;

        mServiceHandler.sendMessage(msg);

    }





    @Override

    public int onStartCommand(Intent intent, int flags, int startId) {

        onStart(intent, startId);



        // Whether it can be sent repeatedly

        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;

    }



    @Override

    public void onDestroy(a) {

        mServiceLooper.quit();

    }



    / * *

     * Unless you provide binding for your service, you don't need to implement this

     * method, because the default implementation returns null. 

     * @see android.app.Service#onBind

* /


    @Override

    public IBinder onBind(Intent intent) {

        return null;

    }



    / * *



* This method is executed in child threads and can only execute one event at a time,

* /


    @WorkerThread

    protected abstract void onHandleIntent(Intent intent);

}

Copy the code

Summary: IntentServices is a way to use Service+ HandlerThread. In many cases we can use HandlerThread+ Handler for thread execution and handler distribution of messages.