当前位置: 移动技术网 > 移动技术>移动开发>Android > Android HandlerThread的使用及原理详解

Android HandlerThread的使用及原理详解

2019年07月24日  | 移动技术网移动技术  | 我要评论

一、handlerthread的含义

handlerthread能够新建拥有looper的线程。这个looper能够用来新建其他的handler。(线程中的looper)需要注意的是,新建的时候需要被回调。

二、handlerthread的用法

一般情况下,我们会经常用handler在子线程中更新ui线程,那是因为在主线程中有looper循环,而handlerthread新建拥有looper的子线程又有什么用呢?

必然是执行耗时操作。举个例子,数据实时更新,我们每10秒需要切换一下显示的数据,如果我们将这种长时间的反复调用操作放到ui线程中,虽说可以执行,但是这样的操作多了之后,很容易会让ui线程卡顿甚至崩溃。

于是,就必须在子线程中调用这些了。
handlerthread继承自thread,一般适应的场景,便是集thread和handler之所长,适用于会长时间在后台运行,并且间隔时间内(或适当情况下)会调用的情况,比如上面所说的实时更新。

三、实现每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还在执行
  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();//模拟数据更新
 
        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秒更新一下数据:";
          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还在执行
    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()中的逻辑都是在子线程中运行的。

接下来就是两个关键的方法,run()和getlooper():
run()中可以看到是很简单的创建looper以及让looper工作的逻辑。
run()里面当mlooper创建完成后有个notifyall(),getlooper()中有个wait(),这有什么用呢?因为的mlooper在一个线程中执行创建,而我们的handler是在ui线程中调用getlooper()初始化的。
也就是说,我们必须等到mlooper创建完成,才能正确的返回。getlooper();wait(),notify()就是为了解决这两个线程的同步问题。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网