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

首頁(yè) > 系統(tǒng) > Android > 正文

Android HandlerThread的使用及原理詳解

2019-10-23 18:33:39
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

一、HandlerThread的含義

HandlerThread能夠新建擁有Looper的線程。這個(gè)Looper能夠用來(lái)新建其他的Handler。(線程中的Looper)需要注意的是,新建的時(shí)候需要被回調(diào)。

二、HandlerThread的用法

一般情況下,我們會(huì)經(jīng)常用Handler在子線程中更新UI線程,那是因?yàn)樵谥骶€程中有Looper循環(huán),而HandlerThread新建擁有Looper的子線程又有什么用呢?

必然是執(zhí)行耗時(shí)操作。舉個(gè)例子,數(shù)據(jù)實(shí)時(shí)更新,我們每10秒需要切換一下顯示的數(shù)據(jù),如果我們將這種長(zhǎng)時(shí)間的反復(fù)調(diào)用操作放到UI線程中,雖說(shuō)可以執(zhí)行,但是這樣的操作多了之后,很容易會(huì)讓UI線程卡頓甚至崩潰。

于是,就必須在子線程中調(diào)用這些了。
HandlerThread繼承自Thread,一般適應(yīng)的場(chǎng)景,便是集Thread和Handler之所長(zhǎng),適用于會(huì)長(zhǎng)時(shí)間在后臺(tái)運(yùn)行,并且間隔時(shí)間內(nèi)(或適當(dāng)情況下)會(huì)調(diào)用的情況,比如上面所說(shuō)的實(shí)時(shí)更新。

三、實(shí)現(xiàn)每2秒更新一下UI

public class MainActivity extends AppCompatActivity {   private TextView tvMain;   private HandlerThread mHandlerThread;  //子線程中的handler  private Handler mThreadHandler;  //UI線程中的handler  private Handler mMainHandler = new Handler();   //以防退出界面后Handler還在執(zhí)行  private boolean isUpdateInfo;  //用以表示該handler的常熟  private static final int MSG_UPDATE_INFO = 0x110;   @Override  protected void onCreate(Bundle savedInstanceState)  {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);     tvMain = (TextView) findViewById(R.id.tv_main);     initThread();  }    private void initThread()  {    mHandlerThread = new HandlerThread("check-message-coming");    mHandlerThread.start();     mThreadHandler = new Handler(mHandlerThread.getLooper())    {      @Override      public void handleMessage(Message msg)      {        update();//模擬數(shù)據(jù)更新         if (isUpdateInfo)          mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO);      }    };   }   private void update()  {    try    {      //模擬耗時(shí)      Thread.sleep(2000);      mMainHandler.post(new Runnable()      {        @Override        public void run()        {          String result = "每隔2秒更新一下數(shù)據(jù):";          result += Math.random();          tvMain.setText(result);        }      });     } catch (InterruptedException e)    {      e.printStackTrace();    }   }   @Override  protected void onResume()  {    super.onResume();    //開(kāi)始查詢    isUpdateInfo = true;    mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO);  }   @Override  protected void onPause()  {    super.onPause();    //停止查詢    //以防退出界面后Handler還在執(zhí)行    isUpdateInfo = false;    mThreadHandler.removeMessages(MSG_UPDATE_INFO);  }   @Override  protected void onDestroy()  {    super.onDestroy();    //釋放資源    mHandlerThread.quit();  }}

四、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();    Looper.prepare();    synchronized (this) {      mLooper = Looper.myLooper();      notifyAll();    }    Process.setThreadPriority(mPriority);    onLooperPrepared();    Looper.loop();    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();        } 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;  }}

首先我們可以看到HandlerThread繼承自Thread,因此在run()中的邏輯都是在子線程中運(yùn)行的。

接下來(lái)就是兩個(gè)關(guān)鍵的方法,run()和getLooper():
run()中可以看到是很簡(jiǎn)單的創(chuàng)建Looper以及讓Looper工作的邏輯。
run()里面當(dāng)mLooper創(chuàng)建完成后有個(gè)notifyAll(),getLooper()中有個(gè)wait(),這有什么用呢?因?yàn)榈膍Looper在一個(gè)線程中執(zhí)行創(chuàng)建,而我們的handler是在UI線程中調(diào)用getLooper()初始化的。
也就是說(shuō),我們必須等到mLooper創(chuàng)建完成,才能正確的返回。getLooper();wait(),notify()就是為了解決這兩個(gè)線程的同步問(wèn)題。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到Android開(kāi)發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 二手房| 象州县| 新民市| 桃源县| 福建省| 双城市| 响水县| 民乐县| 荆州市| 河曲县| 长寿区| 绥棱县| 丁青县| 鄱阳县| 蕲春县| 临沭县| 闵行区| 靖宇县| 平和县| 锡林郭勒盟| 淮安市| 张家界市| 余庆县| 宁南县| 容城县| 柘荣县| 德安县| 荥经县| 玉环县| 修水县| 宝清县| 泰州市| 民丰县| 鲜城| 蕲春县| 关岭| 晋城| 武夷山市| 蒙阴县| 崇文区| 揭东县|