HandlerThread详解

转载请标明出处:http://blog.csdn.net/liuhe_5656
简书地址:http://www.jianshu.com/p/5b6c71a7e8d7

概述

在日常开发中,我们经常会通过new Thread(){}.start();的方式来开辟一个新的线程。但是如果我们想要多次执行任务的时候,通过这种方式我就会创建多个线程,这样会使我们的程序运行起来越来越慢。通常情况下我会采用HandlerThread的方式来开辟一个线程,那么HandlerThread是什么呢?今天我们来介绍一下HandlerThread。

正文

HandlerThread是Thread的一个子类,HandlerThread自带Looper使他可以通过消息队列来重复使用当前线程,节省系统资源开销。这是它的优点也是缺点,每一个任务都将以队列的方式逐个被执行到,一旦队列中有某个任务执行时间过长,那么就会导致后续的任务都会被延迟处理。它的使用也比较简单

HandlerThread thread = new HandlerThread("MyHandlerThread");
thread.start();
mHandler = new Handler(thread.getLooper());
mHandler.post(new Runnable(){...});

接下来我们写一个完整的Demo,然后在分析一下它的实现原理。

Demo代码
public class MainActivity extends AppCompatActivity {

    private HandlerThread handlerThread;
    private Handler handler;
    private Button button;
    private int k = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button) findViewById(R.id.button);

        handlerThread = new HandlerThread("suibian");
        handlerThread.start();
        handler = new Handler(handlerThread.getLooper());


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                handler.post(runnable);
            }
        });
    }

    private Runnable runnable = new Runnable() {
        @Override
        public void run() {

            for (int i = 0; i < 5; i++){
                try {
                    Thread.sleep(1000);
                    Log.d("test","第" + k + "个任务--》" + i + "");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            k++;
        }
    };

    @Override
    protected void onDestroy() {
        super.onDes这里写图片描述troy();
        handlerThread.quit();
    }
}

我们连续点击两次Button,让它执行两次任务,我们来看一下它的Log信息。

我们发现它不会立即去执行第二次任务,而是等待第一次任务结束之后再去执行第二次任务,我们来看一下它的原理。

源码分析

我们来看一下HandlerThread的源码

public class HandlerThread extends Thread {
    int mPriority;
    int mTid = -1;
    Looper mLooper;

    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }

            ...

    /**
     * Call back method that can be explicitly overridden if needed to execute some
     * setup before Looper loops.
     */
    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;
    }

        .....

}

它的代码比较短,我们主要来看一下它的run()方法,我们发现它和普通Thread不同之处在于它在run()方法内创建了一个消息队列(如果不太了解消息机制的同学可以看一下Android中的消息机制来了解一下),然后来通过Handler的消息的方式来通知HandlerThread执行下一个具体的任务。由于HandlerThread的run()方法内Looper是个无限循环,所以当我们不需要使用HandlerThread的时候可以通过qiut()的方法来终止。

public boolean quit() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quit();
            return true;
        }
        return false;
    }

quit()实际上就是让run()内的Looper停止循环。

整体流程

当我们使用HandlerThread创建一个线程,它statr()之后会在它的线程创建一个Looper对象且初始化了一个MessageQueue(消息队列),通过Looper对象在他的线程构建一个Handler对象,然后我们通过Handler发送消息的形式将任务发送到MessageQueue中,因为Looper是顺序处理消息的,所以当有多个任务存在时就会顺序的排队执行。当我们不使用的时候我们应该调用它的quit()或者quitSafely()来终止它的循环。

尾语

今天的总结就到这了,如果大家发现不足请留言告知,一定及时修改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值