美文网首页
handler简单研究

handler简单研究

作者: nich | 来源:发表于2021-12-08 14:02 被阅读0次

    handler原理构成了线程模型中简单的生产者-消费者模型:生产者和消费者在同一时间段内共用同一个存储空间,生产者往存储空间中添加数据,消费者从存储空间中取走数据。不管是生产者(子线程)还是消费者(主线程)都只依赖缓冲区(handler),生产者消费者之间不会相互持有,使他们之间没有任何耦合

    1.简单使用

    handler主要看looper,handler,messagequeue

    首先在activitythread里面执行Looper.prepareMainLooper()新建looper

    最后一句话得知通过threadlocal绑定looper来保证一个线程只有一个looper,再看new looper

    新建一个messagequeue来保证一个线程只有一个messagequeue,最后调用looper.loop方法

    上图是阉割过的源码,queue.next()方法是从头部开始取的,看使用

    handler简单使用

    主线程新建handler通过回调handlermessage来接受子线程发送的消息,子线程通过handler的sendmessage方法来发送消息。

    send message

    点击源码可以看都是在handler.java文件下面的

    最终都会走到enqueuemessage上


    msg.target = this

    该代码让msg绑定当前handler,因为匿名内部类都是默认持有外部类的引用的,handler又隐形持有activity对象,所以如果外部的activity要销毁,handler可能有消息还没处理,垃圾回收机制就无法回收activity造成内存泄漏(解决办法弱引用)

    queue.enqueuemessage

    调用messagequeue里面的方法

    msg是个单链表优先级队列,以时间为顺序

    总结

    1.handler使用sendmessage把message通过enqueuemessage丢到messagequeue里面再由loop对象调用looper方法,通过messagequeue里面的.next方法取出来再调用handler的dispatchmessage方法丢出去。

    从某地偷的图

    问题

    1.handler是怎么保证线程安全的

    这里使用synchronized锁是一个内置锁,来保证message进入messagequeue和出去next()不会混乱,因为一个线程只有一个messagequeue,主线程一次都只会处理一个消息,其他的都需要等待,那么这个时候消息队列就不会出现混乱。

    2. 一个线程有几个 Handler?

    这不是你随便你想创建几个就有几个

    3.一个线程有几个 Looper?如何保证?

    一个线程只有一个looper,因为新建looper时候调用prepare时候里面有个threadlocal方法来保证一个线程只有一个looper

    4.Handler内存泄漏原因? 为什么其他的内部类没有说过有这个问题?

    msg绑定当前handler,因为匿名内部类都是默认持有外部类的引用的,handler又隐形持有activity对象,所以如果外部的activity要销毁,handler可能有消息还没处理,垃圾回收机制就无法回收activity造成内存泄漏(解决办法弱引用)

    5.为何主线程可以new Handler?如果想要在子线程中new Handler 要做些什么准备?

    主线程的activitythread里面已经帮你创建好了,子线程创建handler需要新建looper.prepare,looper.loop,looper.quit

    6.子线程中维护的Looper,消息队列无消息的时候的处理方案是什么?有什么用?

    当没有消息的时候在messagequeue的next方法里面有个nativePollOnce休眠了,调用quit然后退出了looper

    7.既然可以存在多个 Handler 往 MessageQueue 中添加数据(发消息时各个 Handler 可能处于不同线程),那它内部是如何确保线程安全的?取消息呢?

    答案见上文

    8.我们使用 Message 时应该如何创建它?

    obtain,享元机制,避免重复创建message导致内存抖动造成可能的oom

    9.Looper死循环为什么不会导致应用卡死

    loop无限循环用于取出消息并将消息分发出去,没有消息时会阻塞在queue.next()里的nativePollOnce()方法里,Android的绝大部分操作都是通过Handler机制来完成的,如果没有消息,则不需要程序去响应,就不会有ANR。ANR一般是消息的处理过程中耗时太长导致没有及时响应用户操作

    乱七八糟的东西记录在后面

    1.如果有个message需要立即处理怎么办。

    调用这个方法他新建一个message没有target,

    在看next()方法,他首先会循环遍历取出msg.target==null的msg进行处理

    同步屏障的设置可以方便地处理那些优先级较高的异步消息。当我们调用Handler.getLooper().getQueue().postSyncBarrier() 并设置消息的 setAsynchronous(true) 时,target 即 为 null ,也就开启了同步屏障。当在消息轮询器 Looper 在 loop() 中循环处理消息时,如若开启了同步屏障,会优先处理其中的异步消息,而阻碍同步消息。屏幕点击的时候会使用,最后记得要移除同步屏障

    2.子线程怎么创建handler

    自己在线程里创建loop,然后调用handler = new handler(thread.loop),有问题,可能你线程的loop还没创建完就执行handler出错了,系统使用handlerthread完成了这个东西

    当你使用getlooper的时候只能等上面的run方法执行完才能执行getlooper方法

    相关文章

      网友评论

          本文标题:handler简单研究

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