Android HandlerThread实现原理详解

HandlerThread 继承于 Thread,所以它本质就是个 Thread。与普通 Thread 的区别在于,它不仅建立了一个线程,并且创建了消息队列,有自己的 Looper,可以让我们在自己的线程中分发和处理消息,并对外提供自己的 Looper 的 get 方法。

HandlerThread 自带 Looper 使它可以通过消息队列来重复使用当前线程,节省系统资源开销。这是它的优点也是缺点,每个任务都将以队列的方式逐个被执行到,一旦队列中有某个任务执行时间过长,那么就会导致后续的任务都会被延迟处理。

HandlerTread使用

public class HandlerThreadActivity extends AppCompatActivity {

    private Button mButton;
    private HandlerThread mHandlerThread;
    private Handler mUiHandler;
    private Handler mChildHandler;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);
        initView();

        mHandlerThread = new HandlerThread("HandlerThread");
        mHandlerThread.start();
        mUiHandler = new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                if (msg.what == 2) {
                    mButton.setText("子线程更新");
                }
                return false;
            }
        });
        mChildHandler = new Handler(mHandlerThread.getLooper(), new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                if (msg.what == 1) {
                    try {
                        //子线程模拟延迟处理
                        Thread.sleep(2000);
                        mUiHandler.sendEmptyMessage(2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                return false;
            }
        });

    }

    public void initView() {
        mButton = findViewById(R.id.btn_show);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mChildHandler.sendEmptyMessage(1);
            }
        });
    }
}

源码分析

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

    public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }

    protected void onLooperPrepared() {
    }

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            // 通知取 Looper 的线程,此时 Looper 已经创建好了
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

    public Looper getLooper() {
        if (!isAlive()) {
            return null;
        }

        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    // 如果新线程还未创建 Looper,则等待
                    wait();
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }

    @NonNull
    public Handler getThreadHandler() {
        if (mHandler == null) {
            mHandler = new Handler(getLooper());
        }
        return mHandler;
    }

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

源码很简单,就是在 run 方法中执行 Looper.prepare()、Looper.loop() 构造消息循环系统。外界可以通过 getLooper() 这个方法拿到这个 Looper。

总结为下:

https://github.com/Omooo/Android-Notes/blob/master/blogs/Android/HandlerThread.md

教程来源于Github,感谢zhpanvip大佬的无私奉献,致敬!

技术教程推荐

朱赟的技术管理课 -〔朱赟〕

邱岳的产品手记 -〔邱岳〕

Nginx核心知识150讲 -〔陶辉〕

浏览器工作原理与实践 -〔李兵〕

技术面试官识人手册 -〔熊燚(四火)〕

如何成为学习高手 -〔高冷冷〕

如何落地业务建模 -〔徐昊〕

讲好故事 -〔涵柏〕

云时代的JVM原理与实战 -〔康杨〕