天天看點

Android HandlerThread源碼分析

文章目錄

      • HandlerThread源碼分析
        • 前言
        • 基本使用
        • 源碼分析

HandlerThread源碼分析

前言

HandlerThread繼承于Thread類,是Android裡的一個封裝類,可以快速建立一個帶有Looper對象的新線程。其本質是Thread+Handler。

HandlerThread可以用來執行多個耗時任務,不需要多次開啟線程。

基本使用

//建立HanderThread對象
HandlerThread workThread = new HandlerThread("workThread");
//啟動工作線程,必須首先被調用
workThread.start();

//建立工作線程的Handler
Handler workHandler = new Handler(workThread.getLooper()) {
    @Override
    public void handleMessage(Message msg) {
        //TODO 在工作線程中處理耗時任務
    }
};

//發送消息
Message message = Message.obtain();
message.what = 1;
workHandler.sendMessage(message);

//結束線程
workThread.quit();
           

源碼分析

public class HandlerThread extends Thread {
    //線程優先級
    int mPriority;
    //線程id
    int mTid = -1;
    //目前線程持有的Looper對象
    Looper mLooper;

    //構造函數
    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }
    //構造函數,設定優先級
    public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }  

    //調用Thread#start()後回調該方法
    @Override
    public void run() {
        //擷取目前線程id
        mTid = Process.myTid();
        //建立Looper對象
        Looper.prepare();
        //通過鎖機制擷取目前線程的Looper對象
        synchronized (this) {
            mLooper = Looper.myLooper();
            //通知getLooper()中的wait()
            notifyAll();
        }
        //設定目前線程的優先級
        Process.setThreadPriority(mPriority);
        //消息循環前執行,方法體是空的,子類可實作
        onLooperPrepared();
        //進行消息循環,從MessageQueue中擷取消息并分發消息
        Looper.loop();
        mTid = -1;
    }

    protected void onLooperPrepared() {
    }

    //擷取目前線程的Looper對象
    public Looper getLooper() {
        //若線程不是存活的,則傳回null
        if (!isAlive()) {
            return null;
        }
        //若目前線程存活,再判斷目前線程的Looper是否被建立
        //Looper對象建立未成功,則阻塞
        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    //wait()阻塞等待
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }

    //停止消息循環,效率高,但線程不安全
    //會調用Looper.quit(),最終調用MessageQueue.quit()
    //周遊Message連結清單,移除所有消息
    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;
    }
}
           

繼續閱讀