Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android ——對HandlerThread的理解和注意事項

Android ——對HandlerThread的理解和注意事項

編輯:關於Android編程

源碼分析

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使他可以通過消息隊列來重復使用當前線程,節省系統資源開銷。這是它的優點也是缺點,每一個任務都將以隊列的方式逐個被執行到,一旦隊列中有某個任務執行時間過長,那麼就會導致後續的任務都會被延遲處理。

2、android系統提供的Handler類內部的Looper默認綁定的是UI線程的消息隊列,對於非UI線程又想使用消息機制,只能自定義一個線程,在線程run()方法中,通過 Looper.prepare();Looper.loop();來開啟Looper和消息隊列,其實就是Google攻城獅給我實現好的HandlerThread,HandlerThread綁定的是它自己的消息隊列,它不會干擾或阻塞UI線程。IntentService內置的是HandlerThread作為異步線程。

注意事項

一旦我們使用了HandlerThread,需要特別注意給HandlerThread設置不同的線程優先級,CPU會根據設置的不同線程優先級對所有的線程進行調度優化。

適用場景

因為HandlerThread擁有自己的消息隊列,它不會干擾或阻塞UI線程,比較合適處理那些需要花費時間偏長的任務。我們只需要把任務發送給HandlerThread,然後就只需要等待任務執行結束的時候通知返回到主線程就好了。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved