源码分析

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();        //prepare()方法中创建了一个Looper对象,并且把该对象放到了该线程范围内的变量中(sThreadLocal),在Looper对象的构造过程中,初始化了一个MessageQueue,作为该Looper对象成员变量。        Looper.prepare();// 为子线程创建Looper 和 MessageQueue        synchronized (this) {            mLooper = Looper.myLooper();            notifyAll();// 通知getLooper()方法Looper创建好了        }        Process.setThreadPriority(mPriority);        onLooperPrepared();        Looper.loop();//开启Looper,不断的循环从MessageQueue中取消息处理了,当没有消息的时候会阻塞,有消息的到来的时候会唤醒        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();// 等待run()方法中Looper创建完成                } 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;    }}

用法

1、创建一个HandlerThread,即创建了一个包含Looper的线程。

HandlerThread handlerThread = new HandlerThread("test");handlerThread.start(); // 开启线程

2、获取HandlerThread的Looper。

Looper looper = handlerThread.getLooper();

3、创建Handler,通过Looper初始化。

Handler handler = new Handler(looper);

现在我们通过handler发送消息,就会在子线程中执行。

用完后一定要记得退出HandlerThread。

handlerThread.quit();

和普通Thread的不同

1、区别
HandlerThread继承自Thread,调用start()实际上是调用了底层run方法,同时创建了一个含有消息队列的Looper,并对外暴露接口(getLooper()),提供自己这个Looper对象,Looper.loop()方法默认是死循环,线程运行完成或程序退出需要手动关闭这个Looper,这就是它和普通Thread的不同。

2、优势
1、我们平常在开发中经常使用new Thread(){}.start()这种方式开启一个子线程,这会创建多个匿名线程,占用系统资源,而HandlerThread自带Looper使他可以通过消息队列来重复使用当前线程,节省系统资源开销。这是它的优点也是缺点,每一个任务都将以队列的方式逐个被执行到,一旦队列中有某个任务执行时间过长,那么就会导致后续的任务都会被延迟处理。

2、android系统提供的Handler类内部的Looper默认绑定的是UI线程的消息队列,对于非UI线程又想使用消息机制,只能自定义一个线程,在线程run()方法中,通过 Looper.prepare();Looper.loop();来开启Looper和消息队列,其实就是Google攻城狮给我实现好的HandlerThread,HandlerThread绑定的是它自己的消息队列,它不会干扰或阻塞UI线程。IntentService内置的是HandlerThread作为异步线程。

注意事项

一旦我们使用了HandlerThread,需要特别注意给HandlerThread设置不同的线程优先级,CPU会根据设置的不同线程优先级对所有的线程进行调度优化。

适用场景

因为HandlerThread拥有自己的消息队列,它不会干扰或阻塞UI线程,比较合适处理那些需要花费时间偏长的任务。我们只需要把任务发送给HandlerThread,然后就只需要等待任务执行结束的时候通知返回到主线程就好了。

更多相关文章

  1. 【摘录】Android的线程使用来更新UI----Thread、Handler、Looper
  2. Android消息循环机制
  3. android 多线程编程
  4. Android 页面自动跳转方法(比如进入app的广告,通过Timer计时器,通过
  5. Android 学习系列 - 线程模型

随机推荐

  1. [原] Android中怎么将图片平铺
  2. 摘要:HenCoder Android(安卓)自定义 View
  3. 如何把React Native嵌入到原生android应
  4. Android新技术------Android(安卓)App Bu
  5. Android源码下载及开发环境的搭建
  6. Android(安卓)ViewPager 打造炫酷欢迎页
  7. android中定时-开“关机”的实现
  8. android各种ui效果库
  9. Android(安卓)4.0 消息广播无法接收的原
  10. [置顶] Android学习之Build环境初探