在进行Android开发很多时候都会用到线程调度,使用较多的就是Handler和Thread,其实Android还为我们封装了他们的结合体HandlerThread,那么他是个什么东西呢,又是怎么工作的,我们今天就来从源码角度来分析一下HanderThread

我们知道在线程里面创建Handler需要先调用Looper.prepare()创建looper,最后调用Looper.loop()开启循环,使用示例代码如下:

 new Thread(){            @Override            public void run() {                Looper.prepare();                handler = new Handler(){                    @Override                    public void handleMessage(Message msg) {                        super.handleMessage(msg);                    }                };                Looper.loop();            }        }.start();

一不小心忘记创建了looper可能会报错,或者忘记开启了消息队列的循环可能导致消息不能得到处理,有没有把这些都封装好的接口可供我们调用呢,这就是我们今天要讲的HandlerThread。我们先看看HandlerThread的使用方法:

            HandlerThread handlerThread = new HandlerThread("test");            handlerThread.start();            handler = new Handler(handlerThread.getLooper());    }
  1. 有没有感觉到代码简洁了许多,可读性增强了很多,那么他内部实现的原理是怎样的呢,在此之前最好先了解Handler+Looper+MessageQueue+Message,可以参考源码解析Handler,了解了Handler的创建和消息处理流程后我们再来看看HandlerThread的源码:
public class HandlerThread extends Thread {    int mPriority;    int mTid = -1;    Looper mLooper;    private @Nullable Handler mHandler;    public HandlerThread(String name) {        super(name);        mPriority = Process.THREAD_PRIORITY_DEFAULT;    }

可以看到HandlerThread实际上是继承了Thread,等同于我们new Thread()而Thread又是实现了Runnable类:

publicclass Thread implements Runnable {    /* Make sure registerNatives is the first thing  does. */    /**     * The synchronization object responsible for this thread's join/sleep/park operations.     */    private final Object lock = new Object();
  1. 接着我们调用了handlerThread.start(),看一下这个start方法里面干了什么:
  /**     * Causes this thread to begin execution; the Java Virtual Machine     重点在这,调用了start(方法后系统会回调run方法)     * calls the run method of this thread.     * 

。。。。。。 public synchronized void start() { // Android-changed: throw if 'started' is true if (threadStatus != 0 || started) throw new IllegalThreadStateException(); group.add(this); started = false; try { nativeCreate(this, stackSize, daemon); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } }

从上面的注释可以看到系统会回调run方法,而HandlerThread继承了Thread且重写了run方法,所以最终回调执行的是HandlerThread里面的run方法,看下HandlerThread里面的run方法的实现:

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

可以看到之前需要自己手动操作的行为只要调用一下start,内部都给你封装好了,同时还提供了获取looper的方法,用于创建Handler的时候传入,因为此handler发出消息的执行是在UI线程还是工作线程执行就是取决于我们传入的Looper对象是在UI线程创建的还是在工作线程创建的,详细说明可以参考上面链接的Handler文章的相关知识:

    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();                } catch (InterruptedException e) {                }            }        }        return mLooper;    }

到此,应该可以看明白了,HandlerThread的工作原理其实和new Thread+Handler的相同,区别就是HandlerThread的使用更加友好,使用者不需要关注更多的内部实现细节,减少了使用的代价。

更多相关文章

  1. Android(安卓)studio 快捷键汇总
  2. Android切近实战(三)
  3. 使用ProGuard遇到“conversion to Dalvik format failed with er
  4. android+kotlin开发笔记(一)
  5. Android从源码分析一:Looper,Handler消息机制
  6. android XML文件解析之 SAX解析方法
  7. 结合Android浅谈Builder模式
  8. 下载最新Android代码的方法
  9. android-如何在子线程中更新ui

随机推荐

  1. Safari 浏览器中自动填充用户名和密码功
  2. 基于web的机票管理系统设计与实现(二)
  3. RabbitMQ:address (cannot connect to hos
  4. 解读:什么是Java的递归算法?
  5. 双Hadoop集群&双Kerberos kdc认证跨域互
  6. 数据项目生命周期的7个步骤——在业务中
  7. Linux学习--第14周
  8. 圣怀布局,网格(容器,项目,单元,轨道,间距
  9. DSaaS,一个创新的云密码服务
  10. Node实战篇:Nodejs 链接 Mariadb 实例