最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

實(shí)例分析Android中HandlerThread線程用法

 更新時(shí)間:2017年12月14日 15:45:15   作者:WangLei_ClearHeart  
本篇文章主要給大家介紹了Android HandlerThread使用介紹以及源碼解析,有需要的朋友參考學(xué)習(xí)下吧。

一、HandlerThread的介紹及使用舉例             

HandlerThread是什么鬼?其本質(zhì)就是一個(gè)線程,但是HandlerThread在啟動(dòng)的時(shí)候會(huì)幫我們準(zhǔn)備好一個(gè)Looper,并供外界使用,說白了就是使我們?cè)谧泳€程中更方便的使用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了,至于為什么分析源碼的時(shí)候就明白了。

HandlerThread使用簡(jiǎn)單介紹:

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

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

接下來初始化一個(gè)Handler并且將mHandlerThread中的Looper作為構(gòu)造函數(shù)參數(shù)傳遞給Handler:

mHandler = new Handler(mHandlerThread.getLooper())

這樣就保證了Hnadler運(yùn)行在子線程。并且需要在適合的時(shí)機(jī)調(diào)用HandlerThread的quit方法或quitSafely方法,如Activity銷毀的時(shí)候:

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

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

相同點(diǎn):

調(diào)用之后MessageQueue消息隊(duì)列均不在接受新的消息加入隊(duì)列。

不同點(diǎn):

quit方法把MessageQueue消息池中所有的消息全部清空。quitSafely方法只會(huì)清空MessageQueue消息池中所有的延遲消息(延遲消息是指通過sendMessageDelayed或postDelayed等方法發(fā)送的消息),非延遲消息則不清除繼續(xù)派發(fā)出去讓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();
     }
}

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

二、HandlerThread的源碼分析

HandlerThread源碼非常簡(jiǎn)短,出去注釋不到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;
     }
 }

看第一行就知道了其本質(zhì)就是一個(gè)線程。

6-9行以及17-20行構(gòu)造函數(shù),也很簡(jiǎn)單,就是初始化的時(shí)候我們可以定義線程名字,還可以傳入線程優(yōu)先級(jí)。

初始化完成,緊接著調(diào)用start()開發(fā)線程就會(huì)執(zhí)行run方法邏輯。

30-41行代碼,最重要的就是調(diào)用Looper.prepare()以及Looper.loop()方法為我們?cè)谧泳€程準(zhǔn)備好一個(gè)Looper。并且用變量mLooper記錄,調(diào)用getLooper()方法的時(shí)候返回。

但是,細(xì)心的你肯定發(fā)現(xiàn)run()方法中有個(gè)notifyAll(),getLooper()中有個(gè)wait()為什么要加這些鳥玩意?

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

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

HandlerThread 還是比較簡(jiǎn)單理解的,好了,本篇到此為止,希望對(duì)你有幫助。

相關(guān)文章

  • Android如何實(shí)現(xiàn)年月選擇器功能

    Android如何實(shí)現(xiàn)年月選擇器功能

    這篇文章主要介紹了Android如何實(shí)現(xiàn)年月選擇器功能,幫助大家更好的理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下
    2021-03-03
  • Android開發(fā)實(shí)現(xiàn)webview中img標(biāo)簽加載本地圖片的方法

    Android開發(fā)實(shí)現(xiàn)webview中img標(biāo)簽加載本地圖片的方法

    這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)webview中img標(biāo)簽加載本地圖片的方法,結(jié)合實(shí)例形式分析了webview加載本地圖片的步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10
  • Android 動(dòng)態(tài)的顯示時(shí)間

    Android 動(dòng)態(tài)的顯示時(shí)間

    本文給大家分享一段代碼實(shí)現(xiàn)android動(dòng)態(tài)顯示時(shí)間,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2016-12-12
  • XRecyclerView實(shí)現(xiàn)下拉刷新、滾動(dòng)到底部加載更多等功能

    XRecyclerView實(shí)現(xiàn)下拉刷新、滾動(dòng)到底部加載更多等功能

    這篇文章主要為大家詳細(xì)介紹了XRecyclerView實(shí)現(xiàn)下拉刷新、滾動(dòng)到底部加載更多等功能,以及添加header功能的RecyclerView,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • android view轉(zhuǎn)Bitmap生成截圖的方法

    android view轉(zhuǎn)Bitmap生成截圖的方法

    這篇文章主要介紹了android view轉(zhuǎn)Bitmap生成截圖的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09
  • Android  ActionBar控件操作使用詳解

    Android  ActionBar控件操作使用詳解

    這篇文章主要介紹了Android  ActionBar控件操作使用,ActionBar是Android常用的導(dǎo)航控件,位于activity的頂部,用于顯示標(biāo)題,導(dǎo)航icon和actions等等
    2023-04-04
  • Android自定義荷載進(jìn)度的兩種方法

    Android自定義荷載進(jìn)度的兩種方法

    進(jìn)度條在App中非常常見,例如下載進(jìn)度、加載圖片、打開文章、打開網(wǎng)頁等等……本篇文章主要介紹了Android自定義荷載進(jìn)度的兩種方法,有需要的朋友可以了解一下。
    2016-10-10
  • Android仿QQ、微信聊天界面長(zhǎng)按提示框效果

    Android仿QQ、微信聊天界面長(zhǎng)按提示框效果

    最近在工作項(xiàng)目中要實(shí)現(xiàn)一個(gè)長(zhǎng)按提示 “復(fù)制” 的功能,類似于QQ、微信聊天界面長(zhǎng)按提示框效果,本來想偷懶在網(wǎng)上找個(gè)開源的項(xiàng)目用,但是看了好幾個(gè)都不是很滿意,所以就打算按照自己的思路來實(shí)現(xiàn)一個(gè)。下面分享給大家,有需要的朋友們可以參考借鑒。
    2016-11-11
  • Android 動(dòng)態(tài)改變布局實(shí)例詳解

    Android 動(dòng)態(tài)改變布局實(shí)例詳解

    這篇文章主要介紹了Android 動(dòng)態(tài)改變布局實(shí)例詳解的相關(guān)資料,這里舉例說明如何實(shí)現(xiàn)動(dòng)態(tài)改變布局的例子,幫助大家學(xué)習(xí)理解,需要的朋友可以參考下
    2016-11-11
  • Android仿頭條、微信大圖預(yù)覽視圖的方法詳解

    Android仿頭條、微信大圖預(yù)覽視圖的方法詳解

    大圖預(yù)覽應(yīng)該對(duì)大家來說都不陌生,下面這篇文章主要給大家介紹了關(guān)于Android仿頭條、微信大圖預(yù)覽視圖的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03

最新評(píng)論

阿坝县| 民县| 理塘县| 临澧县| 梁河县| 济源市| 洪湖市| 新丰县| 湖南省| 海阳市| 乐业县| 黄平县| 贡觉县| 新郑市| 关岭| 清水县| 信宜市| 宁城县| 五台县| 雅安市| 高平市| 青州市| 罗甸县| 沁水县| 泰兴市| 中方县| 眉山市| 财经| 瑞昌市| 临桂县| 凤城市| 平和县| 石渠县| 太白县| 进贤县| 周口市| 鲁山县| 惠东县| 彭泽县| 丹阳市| 威宁|