Common thread forms of Android multithreading

Common thread forms of Android multithreading

Android multi-threaded series

In addition to the traditional Thread, the threads in Andorid mainly include AsyncTask, HandlerThread, and IntentService.

AsyncTask

AsyncTask is a lightweight asynchronous task class that can not only execute tasks in the background, but also pass the execution progress and final results to the UI thread to update the UI. The bottom layer of AsyncTask is to encapsulate Thread and Handler. AsyncTask is not suitable for performing particularly time-consuming tasks. In this case, it is recommended to use the thread pool for processing

  • 4.core methods

    • onPreExecute: Execute in the main thread, before the asynchronous task is executed, you can do some preparatory work
    • doInBackground: Execute in the thread pool to perform specific asynchronous tasks. In this method, you can call the publishProgress method to update the progress of the task
    • onProgressUpdate: executed in the main thread, it will be called after the publishProgress method is called
    • onPostExecute: Executed in the main thread, will be called after the asynchronous task is executed, and the execution result will be returned
    • onCancelled: Executed in the main thread, it will be called when the asynchronous task is cancelled, so the onPostExecute method will not be called
  • AsyncTask must be loaded in the main thread, which means that the first access to the AsyncTask must occur in the main thread. In Android4.1 and above, it has been automatically completed in the main method of ActivityThread

  • The AsyncTask object must be created in the main thread

  • The execute method of AsyncTask must be called on the UI thread

  • Do not directly call the onPreExecute, doInBackground, onProgressUpdate, onPostExecute methods in the program

  • An AsyncTask object can only be executed once, and the execute method can only be called once, otherwise an IllegalStateException will be reported

  • By default, AsyncTask is executed serially

HandlerThread

  • HandlerThread inherits from Thread
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() {
    }

   //run 
    @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;
        }
        
       //If the thread has been started, wait until the looper has been created.
        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;
    }
 
  • The difference between HandlerThread and ordinary Thread is that it opens the message loop in the run method. The outside world needs to notify the HandlerThread to perform a specific task through the Handler message.
  • Since the run method of HandlerThread is an infinite loop, when HandlerThread is no longer needed, the execution of the thread can be terminated by the quit and quitSafely methods.

IntentService

  • IntentService is an abstract class, so you must create its subclasses to use IntentService
  • IntentService inherits from Service, so it is a special service with a higher priority than ordinary background threads and is not easy to be recycled. It is suitable for performing some high-priority background tasks
  • IntentService encapsulates HandlerThread and Handler
public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;

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

        @Override
        public void handleMessage(Message msg) {
           //onHandleIntent HandlerThread 
            onHandleIntent((Intent)msg.obj);
           //
            stopSelf(msg.arg1);
        }
    }

    public IntentService(String name) {
        super();
        mName = name;
    }

    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

   //onCreate
    @Override
    public void onCreate() {
        super.onCreate();
       //HandlerThread
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
       //HandlerThread run HandlerThread 
        thread.start();
        
       //HandlerThread looper ServiceHandler ServiceHandler HandlerThread 
        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) {
       //IntentService onStartCommand HandlerThread Intent 
        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);
}
 
  • IntentService passes task parameters through Intent. When the task is executed, it will call stopSelf(int startId) to stop the service.
  • The onHandleIntent of IntentService is an abstract method that needs to be implemented by ourselves to handle specific tasks.
  • Every time a background task is executed, the IntentService needs to be started. The IntentService requests the HanderThread to perform tasks through messages. The Looper of the Handler executes tasks sequentially, so IntentService also executes background tasks sequentially.

Welcome to follow my WeChat public account, and look forward to learning, communicating and growing together with you!