国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

實例分析Android中HandlerThread線程用法

2019-10-22 18:20:18
字體:
來源:轉載
供稿:網友

一、HandlerThread的介紹及使用舉例             

HandlerThread是什么鬼?其本質就是一個線程,但是HandlerThread在啟動的時候會幫我們準備好一個Looper,并供外界使用,說白了就是使我們在子線程中更方便的使用Handler,比如沒有HandlerThread我們要在子線程使用Handler,寫法如下:

private Handler mHandler;    @Override     public void run() {        super.run();         Looper.prepare();         mHandler = new Handler(){             @Override             public void handleMessage(Message msg) {             }         };         Looper.loop();}

有了HandlerThread就不用我們自己管理Looper了,至于為什么分析源碼的時候就明白了。

HandlerThread使用簡單介紹:

首先我們要初始化HandlerThread然后調用其start方法,也就是開啟線程:

mHandlerThread = new HandlerThread("mHandlerThread");//這里的mHandlerThread其實就是線程的名字mHandlerThread.start();

接下來初始化一個Handler并且將mHandlerThread中的Looper作為構造函數參數傳遞給Handler:

mHandler = new Handler(mHandlerThread.getLooper())

這樣就保證了Hnadler運行在子線程。并且需要在適合的時機調用HandlerThread的quit方法或quitSafely方法,如Activity銷毀的時候:

@Overrideprotected void onDestroy() {   //   super.onDestroy();   //釋放資源   mHandlerThread.quit();}

quit()與quitSafely()方法比較(這里只說一些結論,源碼可以自己查看):

相同點:

調用之后MessageQueue消息隊列均不在接受新的消息加入隊列。

不同點:

quit方法把MessageQueue消息池中所有的消息全部清空。quitSafely方法只會清空MessageQueue消息池中所有的延遲消息(延遲消息是指通過sendMessageDelayed或postDelayed等方法發送的消息),非延遲消息則不清除繼續派發出去讓Handler去處理。

接下來我們完整看一下HandlerThread例子源碼:

 public class MainActivity extends Activity {     private HandlerThread mHandlerThread;     private Handler mHandler;     private boolean flag;     //     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);        mHandlerThread = new HandlerThread("mHandlerThread");         mHandlerThread.start();         mHandler = new Handler(mHandlerThread.getLooper()) {             @Override             public void handleMessage(Message msg) {                 //                 try {                     Thread.sleep(2000);                 } catch (InterruptedException e) {                     e.printStackTrace();                 }                 if(flag){                     Log.i("HandlerThread", "更新:"+new Random().nextInt(1000));                 }                 mHandler.sendEmptyMessage(1);             }         };     }     @Override     protected void onResume() {         //         super.onResume();         flag = true;         mHandler.sendEmptyMessage(1);     }     @Override     protected void onPause() {         //         super.onPause();         flag = false;     }     @Override     protected void onDestroy() {         //         super.onDestroy();         //釋放資源         mHandlerThread.quit();     }}

運行程序就會在控制臺看到每隔兩秒有Log打出。至于HandlerThrea的使用就到此為止了,看懂上面小例子就差不多了。

二、HandlerThread的源碼分析

HandlerThread源碼非常簡短,出去注釋不到100行,這里就直接全部貼出來了:

 public class HandlerThread extends Thread {     int mPriority;     int mTid = -1;    Looper mLooper;     public HandlerThread(String name) {         super(name);        mPriority = Process.THREAD_PRIORITY_DEFAULT;    }     /**     * Constructs a HandlerThread.     * @param name     * @param priority The priority to run the thread at. The value supplied must be from      * {@link android.os.Process} and not from java.lang.Thread.      */    public HandlerThread(String name, int priority) {        super(name);        mPriority = priority;     }    /**      * Call back method that can be explicitly overridden if needed to execute some      * setup before Looper loops.     */     protected void onLooperPrepared() {     }    @Override    public void run() {         mTid = Process.myTid();         Looper.prepare();         synchronized (this) {            mLooper = Looper.myLooper();             notifyAll();         }        Process.setThreadPriority(mPriority);        onLooperPrepared();         Looper.loop();         mTid = -1;     }     /**      * This method returns the Looper associated with this thread. If this thread not been started      * or for any reason is isAlive() returns false, this method will return null. If this thread       * has been started, this method will block until the looper has been initialized.        * @return The looper.      */     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;     }     /**      * Returns the identifier of this thread. See Process.myTid().      */     public int getThreadId() {         return mTid;     } }

看第一行就知道了其本質就是一個線程。

6-9行以及17-20行構造函數,也很簡單,就是初始化的時候我們可以定義線程名字,還可以傳入線程優先級。

初始化完成,緊接著調用start()開發線程就會執行run方法邏輯。

30-41行代碼,最重要的就是調用Looper.prepare()以及Looper.loop()方法為我們在子線程準備好一個Looper。并且用變量mLooper記錄,調用getLooper()方法的時候返回。

但是,細心的你肯定發現run()方法中有個notifyAll(),getLooper()中有個wait()為什么要加這些鳥玩意?

大家發現沒在HandlerThread 例子中Handler的創建是在主線程完成的,創建的時候需要調用HandlerThread的getLooper()獲取mLooper作為參數傳遞給Handler的構造函數,而Looper的創建是在子線程中創建的,這里就有線程同步問題了,比如我們調用getLooper()的時候HandlerThread中run()方法還沒執行完,mLooper變量還未賦值,此時就執行了wait()等待邏輯,一直等到run()方法中mLooper被賦值,之后立即執行notifyAll(),然后getLooper()就可以正確返回mLooper了。

明白了吧,不明的話這里需要花些時間好好理解下,好了源碼主要部分就分析完了,看到這里相信你對HandlerThread有了一定的了解了。

HandlerThread 還是比較簡單理解的,好了,本篇到此為止,希望對你有幫助。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 西畴县| 蕲春县| 定安县| 玛沁县| 赤峰市| 黔江区| 准格尔旗| 五莲县| 从化市| 伊吾县| 麻江县| 察雅县| 新化县| 叶城县| 贵德县| 武川县| 扶绥县| 恩施市| 桂东县| 静乐县| 西丰县| 云林县| 靖安县| 磴口县| 湘阴县| 石柱| 永嘉县| 内乡县| 韶关市| 永泰县| 田林县| 思茅市| 阳朔县| 昌乐县| 陈巴尔虎旗| 台州市| 册亨县| 新宾| 新安县| 方正县| 洞口县|