扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
o(╥﹏╥)o今天太困了,啥也不想干。就把之前收集的资料拿出来温习一下刚好和大家共享下
新洲网站制作公司哪家好,找成都创新互联!从网页设计、网站建设、微信开发、APP开发、成都响应式网站建设等网站项目制作,到程序开发,运营维护。成都创新互联自2013年创立以来到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选成都创新互联。
之前在" rel="nofollow">GitHub
上更新了些关于面试类的文章,含有从基础到进阶。含有BATJ.字节跳动面试专题,算法专题,高端技术专题,混合开发专题,java面试专题,Android,Java小知识,到性能优化.线程.View.OpenCV.NDK等应有尽有。还有辅之相关的视频+学习笔记
(更多完整项目下载。未完待续。源码。图文知识后续上传github。)
可以点击关于我联系我获取完整PDF
(VX:mm14525201314)
负责跨线程通信,这是因为在主线程不能做耗时操作,而子线程不能更新 UI,所以当子线程中进行耗时操作后需要更新 UI时,通过 Handler 将有关 UI 的操作切换到主线程中执行。
具体分为四大要素:
MessageQueue
(消息队列):负责消息的存储与管Handler.sendMessage()
)和处理相应消息事件Handler.handleMessage()
),按照先进先出执行,Looper
(消息池):负责关联线程以及消息的分发,在MessageQueue
获取 Message,分发给Handler,Looper 创建的时候会创建一个MessageQueue
,调用 loop()
方法的时候消息循环开始,其中会不断调用 messageQueue
的 next()方法,当有消息就处理,否则阻塞在 messageQueue
的next()方法中。当 Looper
的 quit()
被调用的时候会调用messageQueue
的 quit()
,此时 next()
会返回 null,然loop()
方法也就跟着退出。具体流程如下:
Looper
,同时也会在在Looper
内部创建一个消息队列。而在创键 Handler 的Looper
,并通过该 Looper
对象获MessageQueue.enqueueMessage
在消息队列中添Looper.loop()
开启消息循环不断轮询调用MessageQueue.next()
,取得对应的 Message 并且Handler.dispatchMessage
传递给 Handler,最Handler.handlerMessage
处理消息。Looper
,一个 MessageQueen
,可以有多个 HandlerThread(1)
:Looper(1)
: MessageQueue(1)
: Handler(N)
SoftReference
):如果一个对象只具有软引用,则WeakReference
):如果一个对象只具有弱引用,那为什么会导致泄露:
Handler 允许我们发送延时消息,如果在延时期间用户
关闭了 Activity,那么该 Activity 会泄露。 这个泄露
是因为 Message 会持有 Handler,而又因为 Java 的
特性,内部类会持有外部类,使得 Activity 会被
Handler 持有,这样最终就导致 Activity 泄露。
怎么解决:
将 Handler 定义成静态的内部类,在内部持有
Activity 的弱引用,并在 Acitivity
的 onDestroy()
中
调用 handler.removeCallbacksAndMessages(null)
及时移除所有消息。
Android 的 UI 控件不是线程安全的,如果在多线程中并发访问
可能会导致 UI 控件处于不可预期的状态
这时你可能会问为何系统不对 UI 控件的访问加上锁机制呢?因为:
Looer.loop()
方法可能会引起主线程的阻塞,但只要它的消息循环没有被阻塞,能一直处理事件就不ANR
的不是主线程阻塞,而是主线程的 Looper
消息处理过程发生了任务阻塞,无法响应手势操作,不能及时刷新 UI。如果队列中只有这个消息,那么消息不会被发送,而是计算到
时唤醒的时间,先将 Looper
阻塞,到时间就唤醒它。但如果此时要加入新消息,该消息队列的对头跟 delay 时间相比更长,
则插入到头部,按照触发时间进行排序,队头的时间最小、队
尾的时间最大
不可以,因为在主线程中,Activity 内部包含一个 Looper 对
象,它会自动管理 Looper
,处理子线程中发送过来的消息。而
对于子线程而言,没有任何对象帮助我们维护 Looper
对象,所以需要我们自己手动维护。所以要在子线程开启 Handler 要先
创建 Looper
,并开启 Looper
循环
可以通过三种方法创建:
Message m = new Message
Message m = Message.obtain
Message m = mHandler.obtainMessage()
后两者效果更好,因为 Android 默认的消息池中消息数量是 10,而后
两者是直接在消息池中取出一个 Message 实例,这样做就可以避免多
生成 Message 实例。
请查看完整的PDF版
(更多完整项目下载。未完待续。源码。图文知识后续上传github。)
可以点击关于我联系我获取完整PDF
(VX:mm14525201314)
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流