源码分析

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常见面试题总结 1.1
  2. Android(安卓)AsyncTask源码简单分析
  3. Android开发之SurfaceView
  4. Android(安卓)studio爬取网页
  5. Android的线程使用来更新UI----Thread、Handler、Looper、TimerT
  6. android 发送邮件
  7. Android异步消息处理机制完全解析-Handler详解
  8. android 同步框架分析
  9. Android中Handler Runnable与Thread的区别详解

随机推荐

  1. 学习Android中的Adapter
  2. Android完全退出应用程序
  3. Android版本对应的API号
  4. android实现页面下方的Tab效果
  5. 打开系统wifi设置界面
  6. Android实现开机自启动无效问题
  7. Android(安卓)颜色渲染(四) BitmapShader
  8. Android动态权限管理
  9. ue4 创建Android和ios ar应用
  10. android中清空一个表---类似truncate tab