美文网首页
android 多线程 — HandlerThread

android 多线程 — HandlerThread

作者: 前行的乌龟 | 来源:发表于2018-06-04 01:13 被阅读56次

    今天我们来看一个简单的 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();
    

    大家要是吧前面我说 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

          本文链接:https://www.haomeiwen.com/subject/ejassftx.html