当前位置: 首页 > news >正文

驻马店阿里巴巴做网站职业培训网

驻马店阿里巴巴做网站,职业培训网,深圳城市规划设计研究官方网站,wordpress标签管理目录 为什么会有HandlerHandler的原理,以及对象讲解主线程的loop在哪里,为什么主线程loop没有阻塞呢?Looper如何保证唯一Handler为什么会引发内存泄漏呢?Message应该如何创建它? 一、为什么会有Handler 线程分为主线…

目录

  1. 为什么会有Handler
  2. Handler的原理,以及对象讲解
  3. 主线程的loop在哪里,为什么主线程loop没有阻塞呢?
  4. Looper如何保证唯一
  5. Handler为什么会引发内存泄漏呢?
  6. Message应该如何创建它?


一、为什么会有Handler


线程分为主线程(主线程又叫UI线程)和子线程,主线程即ActivityThread,规定只有此线程能操作UI,但我们从后台请求数据,都是在子线程操作,所以需要有人帮忙把线程切换一下,所以就有了Handler。


二、Handler的原理,以及对象讲解


2.1 它是如何子线程和主线程通知?

我们来看看Handler的最最最初的实现。主线程和子线程,子线程的数据需要通知到主线程去,主线程拿到数据以后,就去调用方法去更新UI。那么我们想想,如果你去实现子线程通知主线程,也就是两个线程之间通讯,那么你会使用什么方法?

在这里插入图片描述

使用全局变量!共享成员,比如:

//这里只是简单的介绍了一下
var flag:Boolean = false
Thread(object :Runnable{override fun run() {if (flag) {//调用通知UI更新的方法}}}).start()Thread(object :Runnable{override fun run() {flag = true}}).start()

如下,sendMessage就是上面的一个变化通知,当收到新消息的时候,则会回调handleMessage方法进行操作。

	
handler.sendMessage(uimsg);final Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {getMessage(msg);}
};

2.2 对象讲解:looper,message,messagequeue

Handler当然没有我们上面说的那么简单,只是我们拆开了最初的原理。接下来我们再讲一下Looper对象,我们可以注意到,我们写的最初的线程,执行完就结束了,那么肯定不能结束呀,对吧,因为他要继续监听消息。所以呢,还应该进行如下这样的改进,让它不断的循环:

var flag:Boolean = falseThread(object :Runnable{override fun run() {while (run){if (flag) {//调用通知UI更新的方法}}}}).start()Thread(object :Runnable{override fun run() {flag = true}}).start()

而对应到Handler,Looper就是做这个事情的,我们可以看看源码就会有一个循环,不断的循环处理消息:
在这里插入图片描述因为消息很多(message),所以我们会有一个MessageQueue通道来进行管理、传输以及通知。

消息来了以后,loop收到以后开始发送,loop有一个for循环的功能。这里注意一个问题,loop是已经开始运转了,还是收到消息才开始启动呢?

在这里插入图片描述

没错,是已经运转了。线程一开启,就立马启动了。上面的例子我们可以看到,for已经循环了。

我们可以看看调用handleMessage的源码:
在这里插入图片描述looper在循环,如果有数据则开始调用回调,而通知的方法则在handler里面。

在这里插入图片描述源码的主要方法调用:
在这里插入图片描述
流程示意图:
在这里插入图片描述

2.3 这里有一个疑问,loop是如何知道线程是谁的,queue又是谁的

直接在handler里面创建了looper,所以就知道是谁的了。
在这里插入图片描述而queue则是在looper里面创建的。

在这里插入图片描述


三、主线程的loop在哪里,为什么主线程loop没有阻塞呢?


主线程的loop在哪里,在main方法,ActivityThread里面:

在这里插入图片描述

在这里插入图片描述我们可以注意到,主线程也不会结束,mian方法也有一个loop循环。

在这里插入图片描述
为什么主线程loop没有阻塞呢?但我们看到,其实他还是阻塞的,不阻塞,程序就运行完成了。只不过,他是如何阻塞的?他是有数据刷新才运行,没有数据刷新就阻塞,让出cpu,所以他采用的队列、epoll阻塞,去执行其他的任务,比如刷新ui。



四、Looper如何保证唯一


一个线程只能有一个loop,不可能有多个,因为你调用了looper的loop,后面的代码就不会执行了。
调用两次prepare会崩溃,为什么会崩溃呢?因为一个线程只能有一个looper,源码里面直接报错了:
在这里插入图片描述在这里插入图片描述判断有没有值。有,直接报错,没有就往下执行。这就是它的执行方式。
在这里插入图片描述


五、Handler为什么会引发内存泄漏呢?


Handler是内部类,内部类持有外部类的引用。但为什么其他内部类就可以呢?持有链。长生命周期,持有短生命周期的引用,就会导致无法被释放。

5.1 持有链

首先我们先想想,哪个对象不可能被释放?

在这里插入图片描述

没错,主线程对象。然后主线程对象持有looper,而looper持有messagequeue,而messagequeue持有message,message是一个链表,而message又持有hander,而handler又持有activity,所以长生命周期持有短生命周期activity,那么页面切换,activity就无法得到释放。

在这里插入图片描述在这里插入图片描述

六、Message应该如何创建它?


在这里插入图片描述为什么用2呢?这里要了解一下内存抖动。用第一种,会导致创建大量的对象并销毁对象就是内存抖动。如下这种就是内存抖动。
在这里插入图片描述
解决内存抖动的根本方法,就是内存复用,对象复用。所以我们要调用obtain方法。message是一个链表,存储着message进行复用。
在这里插入图片描述
这里的spool就是一个message。如果你直接new message,那么每次都是一个新的链表,而使用Message的obtain方法,它会进行复用。

http://www.hkea.cn/news/307620/

相关文章:

  • 淄博市 网站建设报价郑州seo外包阿亮
  • 网络服务商是指什么网站优化排名工具
  • 网站优化的分析比较好的品牌策划公司有哪些
  • 国外比较好的资源网站电商运营推广是做什么的
  • 佛山房地产网站建设seo实战培训王乃用
  • 如何做可以赚钱的网站关键词如何快速排名
  • 深圳品牌做网站公司有哪些百度app推广
  • 重庆建设行业信息网站搜狗登录入口
  • 同仁行业网站建设报价北京做的好的seo公司
  • 陕西自助建站做网站郑州外语网站建站优化
  • 小型企业网站系统cilimao磁力猫最新版地址
  • 铁岭网站建设移动网站广东网站seo
  • 网站模板插件sem和seo
  • 用wordpress制作网站模板沈阳seo
  • 优化一个网站多少钱宜昌网站seo
  • 刚做的网站怎么才能搜索到枸橼酸西地那非片功效效及作用
  • 罗湖区网站公司专业模板建站
  • 哪有备案好的网站国产系统2345
  • 网站开发怎么让别人看到最新营销模式有哪些
  • ssm网站开发源码百度推广多少钱一个月
  • 手游门户网站建设appstore关键词优化
  • 齐河网站开发seo服务内容
  • 北京微信网站建设费用想卖产品怎么推广宣传
  • 网站上线的步骤厦门网站推广公司哪家好
  • 网站做app的软件有哪些百度一下你就知道下载
  • 界面设计的重要性百度seo关键词排名推荐
  • 股票做T网站直播营销
  • 北京手机网站建设公司排名技术优化seo
  • wordpress可爱的主题seo优化教程
  • 自己可以申请网站做外卖吗网站描述和关键词怎么写