Android-HandlerThreadに対する理解と注意事項


ソース分析
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() {
    }

    @Override
    public void run() {
        mTid = Process.myTid();
        //prepare()        Looper  ,                   (sThreadLocal), Looper        ,      MessageQueue,   Looper      。
        Looper.prepare();//       Looper   MessageQueue

        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();//   getLooper()  Looper    
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();//  Looper,      MessageQueue       ,           ,            
        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();//   run()   Looper    
                } 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;
    }
}

使用法
1.HandlerThreadを作成します.つまり、Looperを含むスレッドを作成します.
HandlerThread handlerThread = new HandlerThread("test");
handlerThread.start(); //     

2、HandlerThreadのLooperを取得する.
Looper looper = handlerThread.getLooper();

3.Handlerを作成し、Looperで初期化する.
Handler handler = new Handler(looper);

これでhandlerでメッセージを送信すると、サブスレッドで実行されます.
使い終わったらHandlerThreadを脱退することを忘れないでください.
handlerThread.quit();

普通のThreadとは違う
1、区別HandlerThreadはThreadから継承され、start()を呼び出すのは実際には最下位のrunメソッドを呼び出すと同時にメッセージキューを含むLooperを作成し、外部にインタフェース(getLooper()を露出し、自分のこのLooperオブジェクト、Looperを提供する.loop()メソッドのデフォルトはデッドループであり、スレッドの実行が完了したり、プログラムが終了したりするには、このLooperを手動で閉じる必要があります.これは通常のThreadとは異なります.
2、優勢1、我々は普段開発中にnew Thread(){}をよく使う.start()は、複数の匿名スレッドを作成してシステムリソースを占有するサブスレッドを開き、HandlerThreadはLooperを持参してメッセージキューを通じて現在のスレッドを繰り返し使用することができ、システムリソースのオーバーヘッドを節約します.これは、各タスクがキューで1つずつ実行され、キューにタスクが長すぎると、後続のタスクが遅延処理されるという利点と欠点です.
2、androidシステムが提供するHandlerクラス内部のLooperはデフォルトでUIスレッドのメッセージキューにバインドされている.非UIスレッドに対してメッセージメカニズムを使用したい場合、1つのスレッドしかカスタマイズできない.スレッドrun()メソッドではLooper.prepare();Looper.loop();Looperとメッセージキューを開くには、Googleの城を攻めるライオンが私に良いHandlerThreadを実現してくれたのです.HandlerThreadは独自のメッセージキューをバインドしており、UIスレッドを干渉したりブロックしたりしません.InentServiceには、非同期スレッドとしてHandlerThreadが内蔵されています.
注意事項
HandlerThreadを使用すると、HandlerThreadに異なるスレッド優先度を設定することに特に注意する必要があり、CPUは設定された異なるスレッド優先度に基づいてすべてのスレッドをスケジューリング最適化する.
適用シーン
HandlerThreadは独自のメッセージキューを持っているため、UIスレッドを干渉したりブロックしたりすることはなく、時間がかかるタスクを処理するのに適しています.私たちはHandlerThreadにタスクを送信し、タスクの実行が完了するのを待つだけで、メインスレッドに戻ることを通知すればいいだけです.