android 多线程 场景,精选Android初中级面试题 (三): 深探Handler,多线程,Bitmap

码个蛋(codeegg) 第 930 次推文

作者:Focusing

链接:https://juejin.im/post/5c85cead5188257c6703af47

Handler

1、谈谈消息机制Handler作用 ?有哪些要素 ?流程是怎样的 ?

参考回答:负责跨线程通信,这是因为在主线程不能做耗时操作,而子线程不能更新UI,所以当子线程中进行耗时操作后需要更新UI时,通过Handler将有关UI的操作切换到主线程中执行。

具体分为四大要素:

Message(消息):需要被传递的消息,消息分为硬件产生的消息(如按钮、触摸)和软件生成的消息。

MessageQueue(消息队列):负责消息的存储与管理,负责管理由 Handler发送过来的Message。读取会自动删除消息,单链表维护,插入和删除上有优势。在其next()方法中会无限循环,不断判断是否有消息,有就返回这条消息并移除。

Handler(消息处理器):负责Message的发送及处理。主要向消息池发送各种消息事件(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对象获得消息队列,然后Handler在子线程中通过MessageQueue.enqueueMessage在消息队列中添加一条Message。

通过Looper.loop() 开启消息循环不断轮询调用 MessageQueue.next(),取得对应的Message并且通过Handler.dispatchMessage传递给Handler,最终调用Handler.handlerMessage处理消息。

2、一个线程能否创建多个Handler,Handler跟Looper之间的对应关系 ?

参考回答:一个Thread只能有一个Looper,一个MessageQueen,可以有多个Handler。

以一个线程为基准,他们的数量级关系是:Thread(1) : Looper(1) : MessageQueue(1) : Handler(N)。

3、软引用跟弱引用的区别

参考回答:

软引用(SoftReference):如果一个对象只具有软引用,则内存空间充足时,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以一直被程序使用。

弱引用(WeakReference):如果一个对象只具有弱引用,那么在垃圾回收器线程扫描的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。

两者之间根本区别在于:只具有弱引用的对象拥有更短暂的生命周期,可能随时被回收。而只具有软引用的对象只有当内存不够的时候才被回收,在内存足够的时候,通常不被回收。

推荐文章:Java中的四种引用类型:强引用、软引用、弱引用和虚引用(https://segmentfault.com/a/1190000015282652)

4、Handler 引起的内存泄露原因以及最佳解决方案

泄露原因:Handler 允许我们发送延时消息,如果在延时期间用户关闭了 Activity,那么该 Activity 会泄露。这个泄露是因为 Message 会持有 Handler,而又因为 Java 的特性,内部类会持有外部类,使得 Activity 会被 Handler 持有,这样最终就导致 Activity 泄露。

解决方案:将 Handler 定义成静态的内部类,在内部持有Activity的弱引用,并在Acitivity的onDestroy()中调用handler.removeCallbacksAndMessages(null)及时移除所有消息。

29d2d866c73cfd4546fc35e5947f9968.gif

点击播放 GIF 0.0M

5、为什么系统不建议在子线程访问UI?

参考回答:Android的UI控件不是线程安全的,如果在多线程中并发访问可能会导致UI控件处于不可预期的状态。

这时你可能会问为何系统不对UI控件的访问加上锁机制呢?因为:

加锁机制会让UI访问逻辑变的复杂

加锁机制会降低UI的访问效率,因为加锁会阻塞某些线程的执行

6、Looper死循环为什么不会导致应用卡死?

参考回答:

主线程的主要方法就是消息循环,一旦退出消息循环,那么你的应用也就退出了,Looer.loop()方法可能会引起主线程的阻塞,但只要它的消息循环没有被阻塞,能一直处理事件就不会产生ANR异常。

造成ANR的不是主线程阻塞,而是主线程的Looper消息处理过程发生了任务阻塞,无法响应手势操作,不能及时刷新UI。

阻塞与程序无响应没有必然关系,虽然主线程在没有消息可处理的时候是阻塞的,但是只要保证有消息的时候能够立刻处理,程序是不会无响应的。

7、使用Handler的postDealy后消息队列会有什么变化?

参考回答:如果队列中只有这个消息,那么消息不会被发送,而是计算到时唤醒的时间,先将Looper阻塞,到时间就唤醒它。但如果此时要加入新消息,该消息队列的对头跟delay时间相比更长,则插入到头部,按照触发时间进行排序,队头的时间最小、队尾的时间最大。

8、可以在子线程直接new一个Handler吗?怎么做?

参考回答:不可以,因为在主线程中,Activity内部包含一个Looper对象,它会自动管理Looper,处理子线程中发送过来的消息。而对于子线程而言,没有任何对象帮助我们维护Looper对象,所以需要我们自己手动维护。所以要在子线程开启Handler要先创建Looper,并开启Looper循环

推荐文章:Android异步消息处理机制完全解析,带你从源码的角度彻底理解(https://blog.csdn.net/guolin_blog/article/details/9991569)

9、Message可以如何创建?哪种效果更好,为什么?

参考回答:可以通过三种方法创建:

直接生成实例Message m = new Message

通过Message m = Message.obtain

通过Message m = mHandler.obtainMessage()

后两者效果更好,因为Android默认的消息池中消息数量是10,而后两者是直接在消息池中取出一个Message实例,这样做就可以避免多生成Message实例。

线程

1、线程池的好处?四种线程池的使用场景,线程池的几个参数的理解?

使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或则“过度切换”的问题,归纳总结就是:

重用存在的线程,减少对象创建、消亡的开销,性能佳。

可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。

提供定时执行、定期执行、单线程、并发数控制等功能。

Android中的线程池都是直接或间接通过配置ThreadPoolExecutor来实现不同特性的线程池.Android中最常见的类具有不同特性的线程池分别为:

newCachedThreadPool:只有非核心线程,最大线程数非常大,所有线程都活动时会为新任务创建新线程,否则会利用空闲线程 ( 60s空闲时间,过了就会被回收,所以线程池中有0个线程的可能 )来处理任务.

优点:任何任务都会被立即执行(任务队列SynchronousQuue相当于一个空集合);比较适合执行大量的耗时较少的任务.

newFixedThreadPool:只有核心线程,并且数量固定的,所有线程都活动时,因为队列没有限制大小,新任务会等待执行,当线程池空闲时不会释放工作线程,还会占用一定的系统资源。

优点:更快的响应外界请求

newScheduledThreadPool:核心线程数固定,非核心线程(闲着没活干会被立即回收数)没有限制.

优点:执行定时任务以及有固定周期的重复任务

newSingleThreadExecutor:只有一个核心线程,确保所有的任务都在同一线程中按序完成

优点:不需要处理线程同步的问题

通过源码可以了解到上面的四种线程池实际上还是利用 ThreadPoolExecutor 类实现的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/507661.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python计算bmi的编程_Python学习-计算BMI的小程序

示例:小明身高1.75,体重80.5kg。请根据BMI公式(体重除以身高的平方)帮小明计算他的BMI指数,并根据BMI指数:低于18.5:过轻18.5-25:正常25-28:过重28-32:肥胖高于32:严重肥…

通过超分辨率重构来提高二维码的对比度

1 问题描述 (1)图像分辨率小。例如一些嵌入在海报(如图1)或远距离拍摄的码,其分辨率远小于通常情况下的码图像。 图1.海报中的二维码占比很小 (2)图像质量较低。有很多是经过了多次的压缩和转…

android web 访问数据库,Web下的JDBC访问数据库的基本步骤

Web下的JDBC访问数据库的基本步骤(2012-06-02 12:09:33)在Java程序中连接数据库的一般步骤分为一下几部分,我摘录出来,跟大家分享。(1)将数据库的JABC驱动加载到classpath中,在基于JavaEE的Web应用开发过程中,通常把JDBC驱动放在W…

linux 磁盘扩容_记录一次ESXi Linux在线扩容,不重启系统

因为工作需要,需要将运行在ESXi主机上面的一台Centos 里面的一个LV卷进行扩容,下面记录了此次扩展的详细过程,整个过程,不需要重启服务器。1. 首先通过df-h 查看当前磁盘结构如下:我们此次的最终目标,就是将…

我目前的主要研究方向

推荐系统 https://blog.csdn.net/search_129_hr/article/details/118680185 游戏难度动态调整 https://blog.csdn.net/search_129_hr/article/details/119204173 睡眠声音识别与增强 https://blog.csdn.net/search_129_hr/article/details/118568452 二维码图像识别与增强…

linux的任务计划6,Linux计划任务

Linux计划任务:未来的某个时间执行一次任务,或者周期性执行某个任务,执行结果会通过邮件通知定时任务:at batch周期性任务:crontab系统任务调度:/ect/crontab用户任务调度:/var/spool/cronmail​…

aws python lambda_python – AWS Lambda发送HTTP请求

这可能是一个简单回答的问题,但我似乎无法弄明白.背景:我有一个python Lambda函数来获取数据库中的更改,然后使用HTTP将json中的更改发布到URL.我正在使用urllib2这样:# this runs inside a loop, in reality my error handling is much betterrequest …

标签分布学习相关研究

1 标记增强及标签分布学习 https://mp.weixin.qq.com/s/cXiR-UeJkcdkljJvE2eERw http://palm.seu.edu.cn/xgeng/files/sc-info18.pdf https://baijiahao.baidu.com/s?id1687693358774525583&wfrspider&forpc https://blog.csdn.net/weixin_42001089/article/details/…

android item三种,Android RecyclerView中的ItemDecoration的几种绘制方法

如题,我们使用recyclerview的时候,如果没有设置显示条目的margin,或者padding的话,是没有分割线效果的。那么除去使用margin或padding,其余的方法是用itemdecoration绘制分割线我们绘制分割线的时候通常会使用drawable去绘制&…

上传文件和提交textfield_0基础掌握Django框架(37)文件上传

为了更好的学习效果,请搭配视频教程一起学习:Django零基础到项目实战 - 网易云课堂​study.163.com文件上传:文件上传是网站开发中非常常见的功能。这里详细讲述如何在Django中实现文件的上传功能。前端HTML代码实现:在前端中&…

2021年第3周LDL方向的周报

LDL小组: 如何快速进入研究状态 (1)系列性的工作,papermaker:读文献,顶刊顶会,综述性文章–》进行扩展,研究主线 (2)接手师兄师姐的工作–》并且对已有的工作…

2021年第3周人工智能方向的周报

快速进入研究: (1)读文献–》综述性的文献–》你自己去综述性文献 (2)已有的工作 (3)有没有相关的数据? 下一步事情: (1)想一想自己的横向做什么…

华为p10刷原生android,华为p10怎么刷机 华为p10刷机方法【详细介绍】

喜欢折腾手机的用户一定对于手机root权限获取不陌生,root后虽然不能享受官方联保服务但同时带来的好处不用小编多说。前面给大家介绍了 华为p10 刷入第三方recovery教程,现在华为p10刷机包已经放出来,小编给大家带来华为p10刷机权限获取教程。…

pythoncookie自动模拟登录_用Python模拟技巧带你实现自动抽屉登录自动点赞

原标题:用Python模拟技巧带你实现自动抽屉登录&自动点赞/1 前言/嘿,各位小伙伴们晚上好呀,今天小编又给大家带来干货内容啦,今天带来的是,如何自动登录抽屉,并且点赞!原计划是不打算使用selenium的,但是…

同学之间互相出的一些有趣题目

题目1:过隧道时间最短问题 四个人(A、B、C、D)晚上过隧道,并且只有一个手电筒,每次只能过两个人,并且还需要有一个人回来传递手电筒,四个人过隧道的速度不一样,分别是1、2、5、10分钟,问怎么过隧道最快?总共用多长时间? 问题扩展&#xf…

android studio sqlitedatabase,在SQLite数据库Android Studio上使用预填充数据库

本问题已经有最佳答案,请猛点这里访问。在这里,我想使用我预先填充的SQLite数据库到我的Android应用程序。 因此,首次运行时,它会自动从assets文件夹中复制数据库,并在我的Android应用程序中将其用作数据库。到目前为止…

使用container的嵌套_ElementUI 技术揭秘(4)— Container 布局容器组件的设计与实现。...

前言上一篇文章我们分析了 Layout 布局组件的设计和实现,它的应用场景通常是局部布局。对于整个页面的布局,element-ui 提供了 Container 布局容器组件,专门用于 PC 管理后台页面的整体布局。需求分析我们先通过几幅图看一下页面的常见布局。…

推荐系统最新研究进展

算法相关的综述 从200多篇顶会论文看推荐系统前沿方向与最新进展 基于强化学习的推荐系统相关研究进展、经典论文整理分享 推荐系统去偏(Debiased Recommendation)研究进展概述 Deep Learning Based Recommender System: A Survey and New Perspectives…

html自动生成在线试题,HTML5测试题整理Ⅰ

1.在 HTML5 中,哪个元素用于组合标题元素?答案:2.HTML5 中不再支持哪个元素?答案:,,,,,,,,,,,3.在 HTML5 中,onblur 和 onfocus 是?答案:事件属性4.在 HTML5 中,新多媒体…

2021年第3周推荐系统方向的周报

1、如何快速进入研究状态 (1)研究方向对应的研究内容 综述性文献 (2)熟悉写文章的规范 表达能力、创新、编码、写作的规范(Latex、如何写标题、如何写摘要、如何画图。。。。),最好是接手师兄师…