The introduction

I’m sure you’ve all been asked this question in your interview, “What about multithreading in Android?” So we have a lot more answers to this question. For example, Thread, Runnable, and ThreadPoolExecutor are common Thread handling methods in Java and Android development. Android provides handlerThreads to ensure Thread safety, efficient Thread communication, and ease of development. AsyncTask IntentService. So today we’re going to talk about IntentService.

Service and IntentService

Not all tasks can be processed in the background, such as time-consuming operations. If we do not start a child thread to process these tasks, we will still cause a lag. In the meantime, the point we need to consider is ANR, which means the application is not responding. For Android, ANR will be generated in different situations as follows:

1. Input events (button and touch events) are not processed within 5s: Input Event Dispatching Out 2. The Event of BroadcaseReceiver (onReceive method) is not handled within the specified time (the foreground broadcast is 10s, and the background broadcast is 60s) : Timeout of broadcast BroadcastRecord 3. Service foreground 20s, background 200s not complete start: Timeout Publishing Content providers Timeout Publishing Content providers Timeout Publishing Content providersCopy the code

As you can see from the above, ANR also occurs in a Service. So if we need to handle time-consuming operations in a Service during development, we can use the IntentService class provided by Android.

IntentService is an abstract class in which the abstract method onHandleIntent is implemented by the developer.

protected abstract void onHandleIntent(@Nullable Intent intent);
Copy the code

IntentService creates a separate worker thread to handle all intent requests, so developers don’t have to deal with multiple threads.

IntentService holds a HandlerThread inside and uses the HandlerThread to process messages

@Override
public void onCreate(a) {
   super.onCreate();
   HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
   thread.start();

   mServiceLooper = thread.getLooper();
   mServiceHandler = new ServiceHandler(mServiceLooper);          
}
Copy the code

IntentService will hold an internal class ServiceHandler

private final class ServiceHandler extends Handler {
   public ServiceHandler(Looper looper) {
      super(looper);
   }

   @Override
   public void handleMessage(Message msg) {
   		// The processing of the current message is handed over to the developer through abstract methods
      onHandleIntent((Intent)msg.obj);
      // After the callback completes, stopSelf is executed to stop the current ServicestopSelf(msg.arg1); }}Copy the code

Msg.arg1 in the stopSelf(msg.arg1) method is an int value that corresponds to the unique identifier of a request. Every time a request is sent, a unique identifier is generated, the request is queued, and when all is done (the last request is equivalent to getLastStartId == startId), Or if the currently sent identifier is the most recently issued one (getLastStartId == startId), our Service will be destroyed.

The onDestory() method is executed on Service destruction to stop the Looper loop inside the IntentService

@Override
public void onDestroy(a) {
   mServiceLooper.quit();
}
Copy the code

Here’s how IntentService works

IntentService IntentService IntentService IntentService IntentService IntentService

public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    @UnsupportedAppUsage
    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(a); mName = name; }public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @Override
    public void onCreate(a) {
        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(a) {
        mServiceLooper.quit();
    }
    
    @Override
    @Nullable
    public IBinder onBind(Intent intent) {
        return null;
    }

    @WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);
}

Copy the code

Conclusion: IntentService source is through internal HandlerThread + Service, I personally feel that the source code reading is helpful to the development of the specification, the development thought of ascension, such as the use of abstract method, inside the IntentService In peacetime our program development process can also refer to this way of code writing.

Multithreaded communication summary list

Android multithreaded communication summary one

Android Multithreaded communication summary ii -IntentService

Android Multithreaded communication Summary three – interview must ask Handler

Android multithreaded communication summary four

I’m Android master. Success isn’t about how much you own, it’s about how many people you’ve helped and how many lives you’ve touched. Thank you, and I’ll see you next time.