面试题:阐述Handler的实现原理

处理过程:
从handler中获取一个消息对象,把数据封装到消息对象中,通过handler的send…方法把消息push到MessageQueue队列中。

Looper对象会轮询MessageQueue队列,把消息对象取出。

通过dispatchMessage分发给Handler,再回调用Handler实现的handleMessage方法处理消息。

流程图:
Handler的实现原理

Handler的实现中适及以下对象:
1、Handler本身:负责消息的发送和处理
2、Message:消息对象
3、MessageQueue:消息队列(用于存放消息对象的数据结构)
4、Looper:消息队列的处理者(用于轮询消息队列的消息对象,取出后回调handler的dispatchMessage进行消息的分发,dispatchMessage方法会回调handleMessage方法把消息传入,由Handler的实现类来处理)

Message对象的内部实现是链表,最大长度是50,用于缓存消息对象,达到重复利用消息对象的目的,以减少消息对象的创建,所以通常我们要使用obtainMessage方法来获取消息对象

安全:Handler的消息处理机制是线程安全

关系:创建Handler时会创建Looper,Looper对象的创建又创建了MessageQueue

如何在子线程创建handler

说明:为何不能直接在子线程中创建handler
解释:在应用App启动的时候,会在执行程序的入口创建一个Looper对象:Looper.prepareMainLooper(),然后Looper.loop();完成Looper对象的创建。实际上Looper.prepareMainLooper()方法还是调用了Looper的prepare()方法完成Looper对象的创建。因此在主线程中通过关键字new创建的Handler对象之前,Looper对象已经存在并始终存在。
1、第一种

在handler前加 Looper.prepare();后加Looper.loop();

new Thread(new Runnable() {
    @Override
    public void run() {
        Looper.prepare();//Looper初始化
        //Handler初始化 需要注意, Handler初始化传入Looper对象是子线程中缓存的Looper对象
        mHandler = new Handler(Looper.myLooper());
        Looper.loop();//死循环
        //注意: Looper.loop()之后的位置代码在Looper退出之前不会执行,(并非永远不执行)
    }
}).start();

2、第二种

在handler构造器中添加 handlerThread.getLooper()

class MainActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val handlerThread = com.example.handlerdemo.HandlerThread()
        handlerThread.start()
        val handler1 = object : Handler(handlerThread.getLooper()) {
            override fun handleMessage(msg: Message?) {
                super.handleMessage(msg)
                Log.d("aaa", "thread:${Thread.currentThread().name},handle message")
            }
        }

        handler1.sendMessage(Message.obtain())
    }
    
}

发布了59 篇原创文章 · 获赞 13 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/Hunter2916/article/details/93744559
今日推荐