HandlerThread

HandlerThread是什么

HandlerThread继承自Thread,因此HandlerThread其实就是一个线程。

线程开启时也就是run方法运行起来后,线程同时创建一个含有消息队列的looper,并对外提供自己这个对象的get方法,这就是

和普通的Thread不一样的地方。可用于多个耗时任务要串行执行

使用流程

//创建mHandlerThread
 HandlerThread mHandlerThread = new HandlerThread("main");
 mHandlerThread .start();

//获取HandlerThead中的Looper
Looper looper = mHandlerThread.getLooper();

//创建子线程中的Looper
Handler handler = new Handler(looper);

//执行耗时操作
handler.post(new Runnable() {
    @Override
    public void run() {
        //子线程中执行耗时操作
    }
});

//界面销毁的时候需要销毁Looper
@Override
protected void onDestroy() {
    super.onDestroy();
    mHandlerThread.quit();
}

IntentService就是由HandlerThread实现的

Android为了方便对Thread和Handler进行封装,也就是HandlerThread。HandlerThread继承自Thread,说白了就是Thread加上一个Looper。源码:

 

可以看到其本身便持有一个Looper对象。

之前学习的时候有两个疑问:

1. HandlerThread为什么start完了之后不会退出?

一般我们都是在某个方法里(如onCreate)调用start方法来启动HandlerThread:

mWorkThread = new HandlerThread("workThread");
mWorkThread.start();

那岂不是在调用完start方法之后就退出了?那这有什么意义,如果是一个普通的线程:

Thread thread = new Thread();
thread.start();

在调用完start()方法之后肯定会退出的。

查看HandlerThread源码:

@Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

当调用完start()方法后系统会自动调用run()方法,run方法里有一个 Looper.loop(); 

 可以看到这个looper方法里有一个死循环,它也是跑在run方法里的,所以HandlerThread在start()完了之后不会立即退出。

2. Handler里的handlerMessage()方法究竟运行于哪个线程?

handlerMessage()方法究竟运行于哪个线程,得看这个方法在哪个线程里被调用,之前分析过handlerMessage是在Looper的loop()方法里辗转被调用的。

 Handler#dispatchMessage()

 

那其实可以这样说,Looper.loop()方法跑在哪个线程,handlerMessage就跑在哪个线程。

对于自定义的Thread+Looper方式:

class LooperThread extends Thread {
      public Handler mHandler;

      public void run() {
          Looper.prepare();

          mHandler = new Handler() {
              public void handleMessage(Message msg) {
                  // process incoming messages here
              }
          };

          Looper.loop();
      }
  }

很明显,handlerMessage()方法跑在子线程。

对于HandlerThread方式:

HandlerThread#run()

@Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

也是跑在子线程。

对于mHandler = new Handler()方式:

虽然未传Looper, 但默认使用的是主线程的Looper, 所以此时handlerMessage跑在主线程。

总结

1、HandlerThread 原理

当系统有多个耗时任务需要执行时,每个任务都会开启个新线程去执行耗时任务,这样会导致系统多次创建和销毁线程,从而影

响性能。为了解决这一问题,Google 提出了HandlerThread,HandlerThread 本质上是一个线程类,它继承了Thread。

HandlerThread 有自己的内部Looper 对象,可以进行loopr 循环。通过获取HandlerThread 的looper 对象传递给Handler 对象,

可以在handleMessage()方法中执行异步任务。

创建HandlerThread 后必须先调用HandlerThread.start()方法,Thread 会先调用run 方法,创建Looper 对象。当有耗时任务进入

队列时,则不需要开启新线程,在原有的线程中执行耗时任务即可,否则线程阻塞。它在Android 中的一个具体的使用场景是

IntentService。由于HanlderThread 的run()方法是一个无限循环,因此当明确不需要再使用HandlerThread 时,可以通过它的quit

或者quitSafely 方法来终止线程的执行。

2、HanlderThread 的优缺点

HandlerThread 优点是异步不会堵塞,减少对性能的消耗。

HandlerThread 缺点是不能同时继续进行多任务处理,要等待进行处理,处理效率较低。

HandlerThread 与线程池不同,HandlerThread 是一个串行队列,背后只有一个线程

 

参考链接https://www.cnblogs.com/yongdaimi/p/11571166.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值