美文网首页
我今天在子线程“更新”了UI操作

我今天在子线程“更新”了UI操作

作者: 眼睛红红红 | 来源:发表于2019-10-08 17:14 被阅读0次

今天闲来无事,突然想来一个问题,我在子线程中更新UI操作会怎么样?当然,老司机肯定知道,这样应用会抛出异常的,然后我做了这个测试,首先我在oncreat方法中做了这一个操作如下图

满心欢喜的运行测试项目,当时内心期待会抛出异常,但是,但是,万万没想到,程序竟然正常,我竟然惊呆了,这是怎么回事,难道是那些传说是假的?我内心有点懵逼了,我转念一想,这个时候UI是不是还没创建呢?oncreat方法中到底做了什么呢?我点开源码去看了一下,

发现oncreat方法中仅仅只是做了配置参数的保存,也就是说这个时候视图并没有创建,那么视图在什么时候创建呢?,我们知道,当生命周期调用了onresume方法时,这个时候activity才会展示在我们眼前,那么这个时候视图才会真正的创建了,也就说viewRootImp这个时候才会添加到decorview中,那么到底是不是在onresume方法中开始显示视图呢?我们看一段代码。

这是activity启动流程中一段代码,了解activity启动流程一定熟悉这段代码,我们可以看到在这里,视图才会真正的展示出来。也就是说在oncreat方法中去调用线程更新UI,这个时候视图还没有创建,所以才会出现上述现象,那么我们将上述方法移到onresume方法中去试试。结果,结果真的出现了

看到这个,我们知道了,原来诚不欺我。那么问题来了,为什么会这样了,也就是为什么不能再子线程中更新UI呢?我们看看更新UI做了什么

继续探究checkForRelayout()方法,

可以看到,每次都会是重绘界面UI,那么我们可以猜一下,是不是因为重绘机制中出现这个限制呢?带着这个疑问我们去看看重绘源码,

没有找到,但是可以看到调用了viewParent的重绘子view的方法,这个viewParent肯定是ViewGroup l 那么我们继续看ViewGroup 中的重绘机制的方法,

凉凉,什么都没看到,头皮发麻,但是突然想到这个方法是实现的啊,那么限制操作是不是在实现之前就做了呢,

没问可以看到调用了parent的重绘方法,那么我们结合上面代码可以知道,这个parent可能是viewRootImp也可能是view,也就是说,这个方法实际是在viewRootImp或者view当中的,首先我们去view中全局搜索这个方法发现没有这个方法,那么可以断定这个方法只能是viewRootImp当中的了,那么我们去看看。

看标记的地方,在重绘开始之前其实就在检查线程了,果然,这一步还是找到了,那么我们猜想慢慢有了结论,现在继续去看这个标记中的方法到底干了什么,

首先检查当前线程如果不是主线程,直接抛出上述异常,也就是我们上面在onresume中操作时候抛出的异常,Soga,这个过程终于被我找到了。

        好了,现在我们来总结下,首先我们在oncreat方法中实现子线程更新UI,这个时候是不会报异常的,因为这个时候视图还没有显示出来,然后在onresume方法操作,这个异常抛出来,那么这个异常怎么产生的呢,因为更新UI是需要重绘的,在viewRootImp中的重绘机制发现,在重绘之前是需要检查线程的,如果当前线程不是主线程的话,那么就会抛出这个异常,但是还有一种方法说,在子线程中更新UI是不安全的,对于这个解释一下,首先这个观点是对的,因为如果两个子线程,其中一个更新UI了,例如:tv.setText("好"),但是另一个子线程也去更新UI,tv.setText("坏"),那么这个UI就会不断被修改,这个肯定是我们不愿意看到的,在主线中因为只有一个主线程,不会存在其他主线程抢占资源去读写UI操作,所以综合上述两个观点,为什么子线程中不能更新UI操作了!!!

相关文章

  • 我今天在子线程“更新”了UI操作

    今天闲来无事,突然想来一个问题,我在子线程中更新UI操作会怎么样?当然,老司机肯定知道,这样应用会抛出异常的,然后...

  • iOS子线程操作UI

    首先声明一点:子线程里面是可以更新UI的。 之所以说子线程不能操作UI是因为UIKit不是线程安全的。UI操作涉及...

  • Android Handler

    Hander机制,将子线程需要更新UI操作信息传递到主线程,从而实现UI更新。 基本写法: ``` Handler...

  • 【Android】AsyncTask源码分析

    在Android中ui是非线程安全的,更新ui只能在主线程操作,所以我们平时如果遇到子线程更新UI的情况,必须要切...

  • Android 关于子线程更新UI的那些事

    一 相信大家都有听过,子线程更新UI的操作。但这种说法,不是很明确。有些人说子线程更新UI会挂,而有些人说子线程可...

  • Android 的线程和线程池

    Android 的线程分为主线程和子线程。 主线程更新 UI 子线程执行耗时操作 AsyncTask封装了线程池和...

  • Handler消息机制

    概念 Android的UI更新是单线程模型,只能在主线程上操作,在子线程上就要通过使用Handler来进行更新UI...

  • iOS多线程之3.NSThread的线程间通信

      我们把一些耗时操作放在子线程,例如下载图片,但是下载完毕我们不能在子线程更新UI,因为只有主线程才可以更新UI...

  • Handler常用的方法

    1.更新UI 更新UI操作必须放在主线程,否则会发生ANR. 子线程发送消息,handler捕获分发。 priva...

  • 理解JS 线程,和Android线程

    1,Android开发都知道,UI线程,和子线程; UI线程:可以操作ui界面, 子线程:不可以操作ui界面 2,...

网友评论

      本文标题:我今天在子线程“更新”了UI操作

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