android不能在主线程,安卓开发:主线程真的不能做UI操作吗?这一点很多程序员都没想到...

只要参与过安卓项目开发一两年的朋友们应该清楚,为了避免UI渲染出现异常安卓框架限制UI操作只能在主线程中进行,如果贸然在子线程做了UI操作结果会怎样?我们随便写下了如下测试代码。

ca981fac72e71ad926b56c4303fcc3aa.png

不出意外的话,代码执行报错抛出了名为CalledFromWrongThreadException异常,这件事告诉我们UI操作必须在主线程中进行。

那么是不是在所有情况下,子线程都不能做UI操作呢?换句话说是不是只要在子线程中操作UI就一定会抛出上述异常呢?今天我们不妨针对这个问题做下研究。

还是以上述代码为例,我们只在布局中把TextView的layout_width改成match_parent的话,业务逻辑什么都不改,再运行一下代码竟然发现一切运行正常。

836b989afa95b76f334f8c145b288b6c.png

怎么样?这种情况你们想到了吗?看到这里有没有颠覆自己的世界观?也就是说主线程里不能操作UI这句话并不是完全正确,那么什么情况下不正确呢?通过上面的例子来看,至少当TextView组件足够大以至于能容纳其内容时上面这句是不正确的,除非你不承认修改TextView文本是UI操作。

ced49c637b97d04f2b9e0b7cd275dae9.png

下面我们试图从源码(Api 28)角度来分析为什么会出现上面这种打破了安卓程序员固有思维的现象,我们先讨论出异常这种情况。从TextView设置文本的方法setText的方法调用栈可知,这个方法会调用View的requestLayout方法,而这个方法最终又会调用ViewRootImpl的checkThread方法,正是在这个方法里抛出了上述异常。

b01d1283563a6cd64f70aa60618e23f5.png

那么我们将TextView的宽度改成足够大的时候,方法的调用栈又会发生什么变化呢?我们再回到TextView的checkForRelayout方法中,在这个方法的8862行是判断TextView是否需要根据文本的内容变化来改变控件的大小。如果控件足够大的话,requestLayout方法将不会调用,所以也不至于去校验布局操作是在哪个线程处理了。

8b320696a99eafbafd985a322db3a63e.png

综上,子线程是可以处理UI操作的,只要没涉及到控件布局变化就行,其实也不仅限于TextView,大家有时间完全可以尝试其他控件如ImageView。

不过虽然在某些情况下可以在子线做UI操作,但是还是不建议那样做,因为在开发过程中很难去判断也没必要去判断文本内容会不会超出控件,作为开发者还是要遵守安卓开发规范尽量保证在主线程里操作UI。不过如果有一天面试的时候有人问你主线程是否可以做UI操作的话,你应该能举出上面这种情况,这样面试官一定会对你刮目相看。

举报/反馈

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

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

相关文章

c++注释快捷键_Jupyter Notebook amp; Lab快捷键大全

Jupyter有两种模式,命令模式和编辑模式,分别有不同的快捷键。编辑模式(按键 Enter 切换):可以往单元中键入代码或文本,此时单元格被蓝色的框线包围,且命令模式下的快捷键不生效; 命令模式 (按键 Esc 开启)&…

多核cpu应用场景_CPU占用100%!PC卡顿原来可以这么解决:多场景多任务也流畅

现代生活里,不论是工作还是生活,多开软件和处理事务可以说都是家常便饭的事情。一边玩着醉心已久的游戏,一边解压着新的电影和游戏;为了查询资料,一不小心打开了数十个网页;复杂繁重的工作铸就了动辄上百兆…

swot分析法案例_项目型销售案例剖析的五大步骤

我们的案例分析方式是根据哈佛大学与中欧国际工商学院的案例分析方法来总结出我们的模式的。这种分析方法包括两种互相关联和依赖的方面。第一方面,就是要对所指定的将供集体讨论的案例,做出深刻而有意义的分析,包括找出案例所描述的情景中存…

autojs 云控_autojs websocket 核心示例代码,云控技术

//初始化方法function recordInit(scriptName){//let ipInfoJson getIP()// let ip ipInfoJson.cip// let location ipInfoJson.cnamelet deviceIMEI ,deviceBrand,deviceModel,AndroidVer,deviceWH,deviceBoard,deviceMac,AndroidIdtry {deviceBrand device.brand;//制造…

定时器和promise_从Promise链理解EventLoop

面试题new Promise(resolve > { setTimeout(()>{ console.log(666); new Promise(resolve > { resolve(); }) .then(() > {console.log(777);}) }) resolve(); }) .then(() > { new Promise(resolve > { resolve(); …

ugui源码_UGUI整体解决方案基础篇(Unity 2019)

课程介绍:本课程是UGUI系列课程的第一篇:基础篇主要是讲解UGUI的基础组件及接口的使用方法,目前UGUI是unity最常用的UI系统,这部分基础只是是每个同学都应该掌握的,这里我就是简单的讲解了用法,大家对UGUI熟…

android 实例源码解释,Android Handler 原理分析及实例代码

Android Handler 原理分析Handler一个让无数android开发者头疼的东西,希望我今天这边文章能为您彻底根治这个问题今天就为大家详细剖析下Handler的原理Handler使用的原因1.多线程更新Ui会导致UI界面错乱2.如果加锁会导致性能下降3.只在主线程去更新UI,轮询处理Handl…

amd cpu排行_最新intel和amd处理器性能排行cpu天梯图2019

现在市面上cpu厂家有很多,比如常见的intel系列的、amd系列CPU,cpu对电脑起着至关重要的作用,所以我们需要知道cpu性能的好坏,为此小编这就给大家带来最新intel和amd处理器性能排行对比天梯图,大家可以了解一下吧。inte…

python中的对象列表_Python内建的对象列表

Python内建的对象列表刚写Python肯定会遇到这样的情况,想写些什么,但又不知从何写起...在我看来问题在于我们不知道有什么东东可以拿来玩,这里列出Python的内建对象,稍微归类了一下,多看几遍代码自然笔上生花&#xff…

电脑会显示android,怎么在电脑上显示、操作安卓手机

想要在电脑上显示、操作安卓手机,该怎么办,那么怎么在电脑上显示、操作安卓手机的呢?下面是学习啦小编收集整理的怎么在电脑上显示、操作安卓手机,希望对大家有帮助~~在电脑上显示、操作安卓手机的方法工具/原料windows操作系统安卓手机电脑…

git version是什么软件_Deepin 15.11 安装 ZoneMinder 视频监控软件

Zoneminder是一款开源的视频监控软件,可以很方便的连接ip摄像头。因计划将家中的监控摄像头引入NAS,在一台deepin系统的笔记本是先进行了测试。UBUNTU和debian系统都是很容易安装这个软件的。未来在NAS上用docker启动一个专门的zoneminder,do…

看不出svp补帧_专业补帧软件SVP4 实现PotPlayer视频补帧教程

虽然能实现帧率翻倍,不过现在视频绝大多数都是24帧或25帧,翻倍也才48帧,没办法实现补帧后达到60帧的效果。SVP4是一款专业版视频补帧软件,提供GPU加速,并允许使用中档CPU和几乎任何GPU硬件为60Hz的FullHD 1080p视频重新…

android 通知历史,Android P新特性:追踪应用通知历史

原标题:Android P新特性:追踪应用通知历史IT之家3月9日消息 不久前,谷歌已经正式推出了首个Android P开发者预览版,包含了许多新特性。对此,IT之家也进行了一系列报道。该系统的新特性也正在不断被发现。例如最新消息显…

文件另存为时名称会改变_易经:人处在困境时,不要焦虑,改变固定习惯,就会迎来转机...

我读《易经》,悟到一些规律:人的一生,起起落落,时而顺利,时而受困,都是正常现象,没有必要把困难和压力看得太重。人处在困境时,不要焦虑,只要改变你的固定习惯&#xff0…

ubuntu系统写路由指令_在Ubuntu中如何查看网络路由表详解,

在Ubuntu中如何查看网络路由表详解,什么是Linux中的路由和路由表?路由的过程意味着IP包在网络上从一点传输到另一点。当你向某人发送电子邮件时,你实际上是在将一系列IP数据包或数据报从你的系统传输到另一个人的计算机上。从计算机发送的数据…

jspdf html转换pdf,使用jspdf将HTML转换为pdf时出错

对于一个角度项目,我试图将包含HTML代码的字符串变量转换为pdf文件。我安置了所有的家属,比如:jspdf格式光栅化HTML我的代码如下:b64DecodeUnicode(str) {return decodeURIComponent(atob(str).split().map(function(c) {return % (00 c.charCodeAt(0).toString(16)).slice(-…

澄海哪里学机器人编程_终于发现小孩有必要学机器人编程吗

让孩子学习编程的目的,就像其他教育方式一样,只是希望能帮助孩子找到他的兴趣点,打开孩子的获取知识和能力的大门。一起来看看一篇小孩有必要学机器人编程吗。小孩有必要学机器人编程吗编程和英语类似,属于基本技能,未…

鸿蒙系统替代iOS,华为横空出世!鸿蒙系统,能否替代安卓IOS?

原标题:华为横空出世!鸿蒙系统,能否替代安卓IOS?从长远来看,华为主推鸿蒙系统是必然的选择。毕竟安卓系统为谷歌的,而由于美国限制,让华为格外被动。命运掌握在自己手里,才有足够的话…

ubuntu安装python3.8_将 Ubuntu 16 和 18 上的 python 升级到最新 python3.8 的方法教程

1. 概述 本文记录在 Ubuntu 16.04 上将 python 升级为 3.8 版本,并配置为系统默认 python3 的过程。 在 Ubuntu 16.04 中,python3 的默认版本为 3.5: $ python3 -V Python 3.5.2 本文以在 Ubuntu 16.04 中安装为例,方法同样适用于…

java怎么表示正无穷大_java中怎样表示一个无穷大? 无穷小?

Java中提供了三个特殊的浮点数值:正无穷大、负无穷大、非数,用于表示溢出和出错。正无穷大:用一个正数除以0将得到一个正无穷大,通过Double或Float的POSITIVE_INFINITY表示。负无穷大:用一个负数除以0将得到一个负无穷…