HandlerThread 总结

来源:互联网 发布:3d外观设计软件 编辑:程序博客网 时间:2024/06/18 18:07

HandlerThread


我们对于HandlerThread的分析从下面三个问题来看

1.HandlerThread是什么?

2.HandlerThread怎么用?

3.HandlerThread的源码?


1.HandlerThread是什么?

HandlerThread本质就是一个普通的Thread,里面建立了Looper

我们一般使用Handler最多的是在主线程(UI线程)中来做UI改变的工作,这个时候关于Handler的初始化操作我们不必关心,因为UI线程自动帮我们做好了,但是如果新建一个Thread在这个新的线程中去使用Handler就要初始化。HandlerThread就是一个Thread,Handler的初始化工作帮我们做好了,HandlerThread是如何做的在后面有讲解

自定义线程中使用Handler的基本操作,Handler详细的请阅读http://blog.csdn.net/chenqianleo/article/details/76977720

   class ThreadWithHandler extends Thread{        Handler mHandler = null;        @Override        public void run() {            super.run();            Looper.prepare();            mHandler = new Handler(){                @Override                public void handleMessage(Message msg) {                    super.handleMessage(msg);                    //自定义处理操作                }            };            Looper.loop();        }    }

2.HandlerThread怎么用?

    //HandlerThread就是一个Thread    HandlerThread handlerThread = new HandlerThread("test_01"){        @Override        protected void onLooperPrepared() {            super.onLooperPrepared();            Log.e(TAG, "onLooperPrepared: " );        }    };    //Thread开始运行    handlerThread.start();    //得到上面HandlerThread线程中初始化完成后的Looper    handler = new Handler(handlerThread.getLooper()){        //以后handler发出的操作就会在HandlerThread线程执行        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            Log.e(TAG, "handleMessage: " + Thread.currentThread().getId() );        }    };

3.HandlerThread的源码?

public class HandlerThread extends Thread {    int mPriority;    int mTid = -1;    Looper mLooper;    //下面2个初始化方法    public HandlerThread(String name) {        super(name);        mPriority = Process.THREAD_PRIORITY_DEFAULT;    }    //设置了优先级,具体的不管    public HandlerThread(String name, int priority) {        super(name);        mPriority = priority;    }    //前面说了HandlerThread是一个Thread,run()方法很重要    //可以发现和我们自定义线程中使用Handler基本相似    @Override    public void run() {        mTid = Process.myTid(); //linux线程的Id        Looper.prepare();  //Looper初始化操作        synchronized (this) {            mLooper = Looper.myLooper();  //得到当前的线程的Looper存储起来            notifyAll(); //这个同步操作和下面的getLooper()方法进行同步操作        }        Process.setThreadPriority(mPriority);         onLooperPrepared(); //这个方法时空实现,我们可以重写它做些操作        Looper.loop(); //Looper循环起来        mTid = -1;    }    //得到当前的Looper    public Looper getLooper() {        //判断当前线程是否存活        if (!isAlive()) {            return null;        }        // If the thread has been started, wait until the looper has been created.        //在我们调用了getLooper()时可能HandlerThread的run()方法还没有执行完毕,此时mLooper还是null,所以需要等待run()方法执行完成后唤醒getLooper()方法,简单说就是同步操作,和Handler没什么关系        synchronized (this) {            while (isAlive() && mLooper == null) {                try {                    wait();                } catch (InterruptedException e) {                }            }        }        return mLooper;    }    }

HandlerThread的特点

HandlerThread将loop转到子线程中处理,将分担MainLooper的工作量,降低了主线程的压力,使主界面更流畅。

开启一个线程起到多个线程的作用。处理任务是串行执行,按消息发送顺序进行处理。HandlerThread本质是一个线程,在线程内部,代码是串行处理的。

但是由于每一个任务都将以队列的方式逐个被执行到,一旦队列中有某个任务执行时间过长,那么就会导致后续的任务都会被延迟处理。

HandlerThread拥有自己的消息队列,它不会干扰或阻塞UI线程。

对于网络IO操作,HandlerThread并不适合,因为它只有一个线程,还得排队一个一个等着。