欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android HandlerThread案例詳解

 更新時(shí)間:2021年08月18日 08:47:18   作者:tandeneck  
這篇文章主要介紹了Android HandlerThread案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下

HandlerThread 顧名思義就是一種可以使用 Handler 的 Thread。日常開(kāi)發(fā)中我們經(jīng)常會(huì)通過(guò)創(chuàng)建一個(gè) Thread 去執(zhí)行任務(wù),有多個(gè)任務(wù)就多創(chuàng)建幾個(gè)線程實(shí)現(xiàn),這時(shí)候可能出現(xiàn)線程同步的問(wèn)題。不過(guò)有時(shí)候我們并不需要很強(qiáng)的并發(fā)性,只需保證按照順序地執(zhí)行各個(gè)任務(wù)即可,有什么好辦法實(shí)現(xiàn)呢?第一反應(yīng)想到的可能是通過(guò) Executors.newSingleThreadExecutor() 方法來(lái)創(chuàng)建一個(gè) SingleThreadExecutor,來(lái)統(tǒng)一所有的任務(wù)到一個(gè)線程中,然后按順序執(zhí)行。其實(shí),除了這個(gè)方法之外,HandlerThread 也可以實(shí)現(xiàn)。

簡(jiǎn)單使用

首先創(chuàng)建一個(gè) HandlerThreadActivity

public class HandlerThreadActivity extends BaseActivity {
    
    private static final String TAG = "HandlerThreadActivity";

    private Button mStartBtn;
    private Handler mHandler;
    private HandlerThread mHandlerThread;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler_thread);
        mStartBtn = findViewById(R.id.start_btn);

        mHandlerThread = new HandlerThread("THREAD_NAME");
        mHandlerThread.start();
        mHandler = new Handler(mHandlerThread.getLooper());

        mStartBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        Log.d(TAG, Thread.currentThread().getId() + " " + String.valueOf((Looper.myLooper() == Looper.getMainLooper())) + " 任務(wù):" + this.hashCode());
                        SystemClock.sleep(3000);
                    }
                });
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mHandlerThread.quit();
    }
}

快速三擊按鈕,打印日志如下:

可以發(fā)現(xiàn),三次不同的任務(wù)按開(kāi)始的順序執(zhí)行,而且是運(yùn)行在子線程中,那到底是怎么實(shí)現(xiàn)的呢?

源碼解析

public class HandlerThread extends Thread {
    int mPriority;
    int mTid = -1;
    Looper mLooper;
    private @Nullable Handler mHandler;

    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() {
        // 獲取線程 id
        mTid = Process.myTid();
        //構(gòu)建一個(gè) Looper
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        //設(shè)置線程優(yōu)先級(jí)
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        // Looper 循環(huán)
        mTid = -1;
    }
    
     // 獲取當(dāng)前線程的 Looper,
    public Looper getLooper() {
        if (!isAlive()) {
            return null;
        }
       
        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }


     /**
     * @return a shared {@link Handler} associated with this thread
     * @hide 方法隱藏掉,無(wú)法調(diào)用
     */
    @NonNull
    public Handler getThreadHandler() {
        if (mHandler == null) {
            mHandler = new Handler(getLooper());
        }
        return mHandler;
    }

     //線程退出方法,主要是調(diào)用 Looper.quit() 方法,不然一直在循環(huán)
    public boolean quit() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quit();
            return true;
        }
        return false;
    }

    //同上,不過(guò)這個(gè)方法會(huì)把消息隊(duì)列中的已有消息處理完才會(huì)安全地退出
    public boolean quitSafely() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quitSafely();
            return true;
        }
        return false;
    }

    public int getThreadId() {
        return mTid;
    }
}

通讀下來(lái),如果熟悉 Handler 原理的同學(xué)大概就明白 HandlerThread 的機(jī)制了:

  • HandlerThread 運(yùn)行 start() 方法,回調(diào) run() 方法。
  • 在 run() 方法中通過(guò) Looper.prepare() 來(lái)創(chuàng)建消息隊(duì)列,并通過(guò) Looper.looper() 方法來(lái)開(kāi)啟消息循環(huán)。
  • 由于 Loop.loop() 是一個(gè)死循環(huán),導(dǎo)致 run() 也是無(wú)線循環(huán),因此當(dāng)我們不需要使用 HandlerThread 的時(shí)候,要調(diào)用它的 quit() 方法或者 quiteSafely() 方法。

到此這篇關(guān)于Android HandlerThread案例詳解的文章就介紹到這了,更多相關(guān)Android HandlerThread內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論