HandlerThread那些事儿

作者: ClericYi | 来源:发表于2020-02-17 09:26 被阅读0次

前言

知识储备:手撕Handler
面试题库:泓洋大神等人的Github项目

虽然HandlerThread其实在我的项目中并没有使用到过,而我现在也是准备面试的一个阶段,学的多也总是没有坏处。

基础用法

// 创建Handler实例
HandlerThread handlerThread  = new HandlerThread("MainActivity");
// 线程启动
handlerThread.start();
// 基于HandlerThread构建的Looper
Handler handler = new Handler(handlerThread.getLooper()){
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                Log.e(TAG, msg.what+"");
            }
        };
// 使用handler发送消息
handler.sendEmptyMessage(1);
// 退出Lopper的死循环
handlerThread.quit();

揭秘HandlerThread

先看看HandlerThread的家庭里有哪些成员呢?

// 一个继承自Thread的类
public class HandlerThread extends Thread {
    int mPriority; // 优先级
    int mTid = -1;
    Looper mLooper; // Looper
    private @Nullable Handler mHandler; // Handler
}

主要的已经标示出解释,因为在之前的手撕Handler已经比较全面的讲解过了Handler以及Looper的作用,这里我们应该也能比较清晰的知道HandlerThread的组成成分应该是Handler+Thread

之前在手撕Handler的讲解中,Looper指的是在ActivityThread中定义的,也就是一个全局型的Looper,并且他的初始化是如下所示的。

Handler handler = new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(@NonNull Message msg) {
                return false;
            }
        });

而这个初始化函数最后调用的Looper也就是我们指的一个全局的Looper
下面给出这个构造函数调用的代码。

public Handler(@Nullable Callback callback, boolean async) {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }

        mLooper = Looper.myLooper(); // 获得ActivityThread中初始化的Looper
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread " + Thread.currentThread()
                        + " that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

这就是HandlerThread中的Handler和上述定义的Handler的区别了,但是他们的工作原理是一致的,只是变化了Looper

使用HandlerThread的优缺点

使用场景:单线程+异步任务场景

优点:

  1. 将loop运行在子线程中处理,减轻了主线程的压力,使主线程更流畅
  2. 串行执行,开启一个线程起到多个线程的作用
  3. 有自己的消息队列,不会干扰UI线程

缺点:

  1. 由于每一个任务队列逐步执行,一旦队列耗时过长,消息延时
  2. 对于IO等操作,线程等待,不能并发

以上就是我的学习成果,如果有什么我没有思考到的地方或是文章内存在错误,欢迎与我分享。


相关文章推荐:
手撕OkHttp
手撕AsyncTask
手撕ButterKnife
手撕Handler

相关文章

网友评论

    本文标题:HandlerThread那些事儿

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