android 多线程 — HandlerThread

今天我们来看一个简单的 HandlerThread,前面我们学习过了 handle ,现在再来看 HandlerThread 会发现真是简单的不得了

HandlerThread 简单的说就是 在一个 Thread 里面封装了一个 looper ,然后启动该 looper ,外接和这个 HandlerThread 的交互都是通过 handle 发送消息,因为 HandlerThread 可以返回其虐不的 looper 对象,然后我们用这个 looper 对象创建 handle 对象发送消息

HandlerThread 的用法


        // 创建 HandlerThread 对象并启动 HandlerThread 所属线程,构造方法需要传线程的名字进去
        HandlerThread handlerThread = new HandlerThread("AAAAAAAA");
        handlerThread.start();

        // 通过 HandlerThread 对象内部的 looper 构建用于通讯的 handle
        Handler otherHandle = new Handler(handlerThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == 1) {
                    Log.d("AAA", Thread.currentThread().getName() + "接受消息" + System.currentTimeMillis());
                }
            }
        };

        // 执行线程间通讯任务
        otherHandle.sendMessage(Message.obtain());

        // 不需要了就关闭线程,
        handlerThread.quit();
        // handlerThread.quitSafely();

大家要是吧前面我说 handle 的那篇搞明白,这 HandlerThread 的使用实在不是要太简单了

看看源码吧


其实猜都能猜到的,这是 HandlerThread 声明的成员变量

public class HandlerThread extends Thread {
    int mPriority;
    int mTid = -1;
    Looper mLooper;
    private @Nullable Handler mHandler;
{

这是核心 run 方法

    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

在线程启动时把 looper 消息队列跑起来

有意思的地方来了

    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;
    }

大家注意 getLooper() 方法是给别的线程调用的,因为 handle 的构造方法不能接受 null 的 looper 对象,要不会抛异常,所以这里在其他线程获取 HandlerThread 的 looper 对象时,若是发现此时 looper 对象是 null 的,那么就会阻塞调用 getLooper() 方法的外部线程。

直到 run 的初始化同步代码段跑完,此时 looper 初始化完成,会主动唤醒所有阻碍在 looper 对象身上的 线程,我们再来看看 HandlerThread 的run 方法

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            // 主动唤醒所有阻碍在 looper 对象身上的 线程
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

好了,HandlerThread 很简单的,这里就基本完事了。我们看 HandlerThread 源码一定要理解 HandlerThread 为啥要 wait,什么时候 notifyAll 。这个是 HandlerThread 里面最值得学习的点,学会了很有用的。

参考资料


  • Android多线程:手把手教你使用HandlerThread
  • Android多线程:这是一份详细的HandlerThread源码分析攻略

你可能感兴趣的:(android 多线程 — HandlerThread)