国产探花免费观看_亚洲丰满少妇自慰呻吟_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ā)表
主站蜘蛛池模板: 哈尔滨市| 苗栗市| 定兴县| 宜丰县| 北碚区| 靖西县| 叙永县| 昌图县| 都昌县| 武宁县| 绵竹市| 全南县| 商水县| 保靖县| 枣阳市| 鹤峰县| 象州县| 左权县| 会东县| 湟源县| 扎兰屯市| 永和县| 利川市| 永川市| 来凤县| 唐河县| 博湖县| 茌平县| 获嘉县| 马山县| 赤水市| 永春县| 徐汇区| 兴义市| 集安市| 长沙县| 渝中区| 蓝山县| 天等县| 翁源县| 淄博市|