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

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

Android HandlerThread的使用及原理詳解

2019-12-12 03:16:59
字體:
供稿:網(wǎng)友

一、HandlerThread的含義

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

二、HandlerThread的用法

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

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

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

三、實現(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    {      //模擬耗時      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();    //開始查詢    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()中的邏輯都是在子線程中運行的。

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

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 深水埗区| 威远县| 修文县| 新安县| 博罗县| 盐城市| 松阳县| 山西省| 镇平县| 边坝县| 衡阳县| 彰化县| 烟台市| 四会市| 吉木乃县| 庆云县| 公安县| 高安市| 武穴市| 新昌县| 泽州县| 尚义县| 浦北县| 雷波县| 鹿邑县| 西青区| 桃园市| 本溪市| 乐都县| 曲阜市| 四平市| 瑞金市| 金昌市| 密云县| 宁都县| 营口市| 科尔| 祁阳县| 彭泽县| 民和| 潼关县|