$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its...Android中相关的view和控件操作都不是线程安全的,所以Android才会禁止在非UI线程更新UI,对于显式的非法操作,比如说直接在Activity里创建子线程,然后直接在子线程中操作UI等,Android...而对于隐式的非法操作,App不会直接简单粗暴地异常退出,只是出现奇怪的结果,Only the original thread that created a view hierarchy can touch...its views便是一个例子,字面意思是只有创建视图层次结构的原始线程才能操作它的View,明显是线程安全相关的。...在4.0之后谷歌强制要求连接网络不能在主线程进行访问 只有主线程(UI线程)才可以更新UI
,可以不设置,做一次性的任务。...$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its...view Android中相关的view和控件操作都不是线程安全的,所以Android才会禁止在非UI线程更新UI,对于显式的非法操作,比如说直接在Activity里创建子线程,然后直接在子线程中操作...its views便是一个例子,字面意思是只有创建视图层次结构的原始线程才能操作它的View,明显是线程安全相关的。...// 一旦计时器被终止,它的执行线程就会顺利地终止,并且不会再安排任务了。
先看看崩溃日志: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created...(DOM是一种文档对象模型,他的层次结构是除了顶级元素,所有元素都被包括到另外的元素节点中,有点像家谱树结构,很典型的就是html代码解析) 到这里,一个有完整view结构的DecorView就创建出来了...currentThread不是mThread的时候,就会崩溃,报的错误是 “只有创建视图层次结构的原始线程才能触摸它的视图” ,看到这里是不是猜到一些了,这个mThread难道就是“创建视图的原始线程”...所以我们就可以得知崩溃的真正原因,就是当前线程不是ViewRootImpl创建时候的线程就会崩溃。...翻译的还是比较准确的,只有创建视图的原始线程才能修改这个视图,听起来也蛮有道理的,我创造了你才有权利改变你,有那味了。
Handler也是个磨人的小妖精,一次又一次的败给她 一、还是以最经典的:子线程更新UI来引入吧 场景:点击按钮新建线程,在新线程里更改TextView的值,如下图 handler1.png...;//更改视图 } }.start(); } } 2.结果: 结果.png 看起来不太好,直接崩了,报了个CalledFromWrongThreadException...:只有创建视图层的那个原始线程(main)才给摸他的视图。...是啊,我穿(main线程)的衣服(View)凭什么给你(其他线程)乱摸(修改...),你又不是我女朋友。...android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view...,异常的起点在最下面,最顶上的是抛出异常的方法栈,我们只需从下往上就可以知道方法的调用顺序了,跟着 TextView 的源码从 setText() 里去查看源码,setText()方法经过多次跳转进入以下方法...ViewRootImpl 是在哪里实例化的,作为单线程模型,我们可以从 应用的 Java 层入口,ActivityThread 也就是 UI 线程的实现类去查看 1131 private class...H Handler实例是核心中的核心,关键中的关键,一句话,我们的所有消息都需要通过它的处理分发,Activity 的生命周期、用户的触碰事件,一切的反馈都是通过这个来交互,如果没有这个,应用就会像一个...= Thread.currentThread()) { 4746 throw new CalledFromWrongThreadException( // 只有创建视图层次结构的原始线程才能访问它的视图
javax.crypto.IllegalBlockSizeException: data not block size aligned 数据块大小未对齐 des加密需要是8的整数倍; android.view.ViewRootImpl...$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its...在子线程是不能更新ui的,可以使用handler将参数传出,进行ui更新; String和byte[]间的转换 byte[] byteArray = str.getBytes(); Caused by:...org.gradle.api.file.UnableToDeleteFileException: Unable to delete directory 'E:\daima_new 重新复制项目到其他目录打开,试试; 这是因为上次编译的缓存没清空导致...错误:Unparseable date: "2020/07/16 14:37:56" (at offset 4) 解释:at offset 4,在16 的地方解析错误,倒叙数4个时间格式; 2020-07
$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its...,不允许在非UI线程中更新UI线程 既然报这个错了,那就跟进去,看看 ViewRootImpl.java 为什么报这个错,之前分享过看源码的方式。...} 当Activity对象被创建完毕后,将DecorView添加到Window中,同时会创建ViewRootImpl对象,在源码中可以看到 mThread 是在ViewRootImpl 的构造方法里这样初始化的...然后再把他设为主线程。...还未创建,它的创建是在 handleResumeActivity() 的调用到 windowManager.addView(decorView) 时候。
我们从一个异常说起: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created...翻译就是说 只有创建了view树的线程,才能访问它的子view。并没有说子线程一定不能访问UI。...那可以猜想到,button的确实是在子线程被添加到window中的,子线程确实可以直接访问,而主线程访问确实会抛出异常。看来可以解释这个错误的原因了。 下面就具体分析下。...一般情况,UI就是指Activity的view,这也是我们通常称主线程为UI线程的原因,其实严谨叫法应该是activity的UI线程。而我们这个例子中,这个子线程也可以称为button的UI线程。...另外注意2,在activity的onCreate到首次onResume的时期,创建子线程在其中更新UI也是可以的。这不是违背上面的结论了吗?
报错说明 直接在子线程更新UI会报CalledFromWrongThreadException错,错误如下: 12-20 15:39:04.730: E/AndroidRuntime(2763):...FATAL EXCEPTION: Timer-0 12-20 15:39:04.730: E/AndroidRuntime(2763): android.view.ViewRootImpl$CalledFromWrongThreadException...: Only the original thread that created a view hierarchy can touch its views. 12-20 15:39:04.730: E/AndroidRuntime...04.730: E/AndroidRuntime(2763): at java.util.Timer$TimerImpl.run(Timer.java:284) 为什么会出现这个问题,这里有一篇大神的解答关于为什么不能再子线程中更新...UI的讨论大神对代码的解读能力让人兴叹,总结来说是因为子线程没有创建Looper.prepare()这个与子线程不能Toast的问题是一样的Toast为什么不可以在子线程里面运行 ---- 解决方案 1
4.使用Android中的消息机制解决:Only the original thread that created a view hierarchy can touch its views 原始代码 public...原因在于,Android系统中的视图组件并不是线程安全的,如果要更新视图,必须在主线程中更新,不可以在子线程中执行更新的操作。...Message msg = new Message(); msg.what = COMPLETED; handler.sendMessage(msg); } } } 通过上面这种方式,我们就可以解决线程安全的问题...,把复杂的任务处理工作交给子线程去完成,然后子线程通过handler对象告知主线程,由主线程更新视图,这个过程中消息机制起着重要的作用。...Android的消息循环是针对线程的,每个线程都可以有自己的消息队列和消息循环。
这个问题的根本原因可以简述为:不可控的动效冲突(业务随机性) + 无从安置的主线程耗时方法(弹窗实例化、视图infalte)。 因此我们要寻求一个方案来解决动效冲突导致的卡顿问题。...= Thread.currentThread()) { throw new CalledFromWrongThreadException( "Only the...仅在view被attach至window时,它才会作为UI的一部分(挂载至ViewTree),需要被固定线程进行控制、更新等管理操作。...= Thread.currentThread()) { throw new CalledFromWrongThreadException( "Only the...Activity的使用必须在主线程,因为其创建等操作中使用的Handler也被强制指定为mainThreadHandler。
说白了就是注意一点:invalidate不能再线程中直接使用,但是可以在UI线程中直接使用,postinvalidate可以直接在线程中使用 我们在应用程序中类是继承View的,它就是一个UI线程,那么它就可以直接使用了...强行访问的话会报:android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a...这时候你需要创建一个继承了android.os.Handler的子类,并重写handleMessage(Message msg)方法。...也就是说:在新线程创建并发送一个Message,然后再主线程中捕获、处理该消息。 3.使用多线程和双缓冲 Android中SurfaceView是View的子类,她同时也实现了双缓冲。...直接在R.java中去找 3.实现自己的自定义Adapter需要去继承BASEAdapter的,BaseAdapter是没有做任何数据的处理,所以你需要重载它的四个函数 @Override public
= Thread.currentThread()) { throw new CalledFromWrongThreadException( "Only...Zygote 进程在系统启动时创建,它预加载了许多常用的类和资源,为应用程序进程提供了一个初始化好的运行环境。当需要创建新的应用程序进程时,系统会通过 Zygote 进程来 fork 出新的进程。...任何线程都可以更新自己创建的 UI,只需要满足以下两种情况在 ViewRootImpl 创建之前,可以在子线程更新 UI,比如在 Activity onCreate 的时候在 ViewRootImpl...创建之后,只需要保证创建 ViewRootImpl 的线程和更新 UI 的线程是同一个就可以;比如我们在子线程调用 ViewManager#addView我们同上说子线程不可以更新 UI,这个异常是在...= Thread.currentThread()) { throw new CalledFromWrongThreadException( "Only
卧槽,不按套路出牌啊,果然漂亮的女人都难搞定。 1)首先,并非在子线程里面更新UI就一定有问题,如下所示的代码,则可以完美更新UI。...$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its..."Only the original thread that created a view hierarchy can touch its views."); } } 如果当前线程不是主线程...可以讲讲吗? 我想...大概,可能是ViewRootImp还没有创建出来吧,所以没有走到checkThread()方法。...到这里可以事后一支烟了,不是,是总结一下了: 1)ViewRootImpl是在Activity的onResume()方法后面创建出来的,所以在onResume之前的UI更新可以在子线程操作而不报错,因为这个时候
$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its...$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its...mThread = Thread.currentThread(); ...代码省略... } 可以发现全类只有这一处对mThread进行了赋值。...已经是顶级View了,它的parent应该就是ViewRootImpl,那么为什么ViewRootImpl是null呢,明明之前已经show过了。...PS:本人还得吐槽一下Android,Android官方一方面明明宣称不能在主线程以外的线程进行UI的更新,另一方面在初始化ViewRootImpl的时候又不把主线程作为成员变量保存起来,而是直接获取当前所处的线程作为
View:作为所有图形的基类。 ViewGroup:对View继承扩展为视图容器类。 Window:它概括了Android窗口的基本属性和基本功能。...setText.png 从上图看在页面进行视图更新的时候会触发 checkThread ,校验当前线程是否是 ViewRootImpl 被创建时所在的线程。...//异常信息,提示当前执行任务的线程与创建ViewRootImpl的线程不一样~!...所以只要避免上面的执行逻辑,还是可以在异步线程操作UI的。...我们可以再异步线程初始化 ViewRootImpl 同时在该线程进行视图更新(eg: Dialog 异步线程的展现,具体参考:Dialog、Toast的Window和ViewRootImpl)。
然而,所显示的信息表明所选线程所花费的时间。例如,如果您正在使用作业系统或多线程呈现,则不包括另一个线程中的处理时间。如果您想要检查,您可以通过选择如图3.8所示的线程来进行检查。...在这种情况下,Raw Hierarchy原始层次结构视图在本例中使用。Raw Hierarchy视图与Hierarchy视图的不同之处在于Calls总是固定为1。...Tips 当打开一个项目时,通常会有一个很深的层次结构。在这种情况下,您可以通过按住Mac上的Option键(Windows上的Alt键)打开层次结构的所有级别。...相反,按住键关闭一个项目将关闭该层次结构下的所有内容 timeline view 在时间轴视图中,层次视图中的项目显示为方框,因此在查看整个视图时,您可以直观地看到加载的位置。...因为它是鼠标可访问的,即使是深层的层次结构也可以通过拖动来掌握。此外,有了时间线,就不需要切换线程;显示所有线程。这样就可以很容易地看到每个线程中什么时候发生了什么类型的处理。
SingleInstance:系统会为它创建一个单独的任务栈,并且这个实例独立运行在一个 task中,这个task只有这个实例,不允许有别的Activity 存在(可以理解为手机内只有一个)。...onDestroyView():当Fragment的UI从视图结构中移除时调用。 onDestroy():销毁Fragment时调用。...newArray(int size):创建指定长度的原始对象数组。 User(Parcel in) 从序列化后的对象中创建原始对象。...= Thread.currentThread()) { throw new CalledFromWrongThreadException( "Only the...Looper,因为默认的 UI 主线程,也就是 ActivityThread,ActivityThread 被创建的时候就会初始化 Looper,这也是在主线程中默认可以使用 Handler 的原因。
EventBus支持线程分发,在上一篇博客EventBus简介以及初步使用中,了解到EventBus的使用主要涉及事件发送者,以及事件订阅者;对于发送和订阅这两个行为,可以在不同的线程中,这就是EventBus...关于线程的设置,可以在订阅方法中使用@Subscribe注解进行线程的调节,如代码所示: @Subscribe(threadMode = ThreadMode.MAIN) public void...$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its...views 可以发现这个异常就是说明不能在非UI线程操作UI。...总结 经过上面的分析,可以知道每种ThreadMode的使用场景以及与post线程不同时,有怎样的表现。
,在接收到信号后进行视图渲染的刷新。...= null) {// 幽灵视图,可以理解为一个状态不可见 view 的拷贝,类似 overlay 图层概念 mGhostView.invalidate(true);...boundingRect.right), (int) Math.ceil(boundingRect.bottom)); } // 循环向上遍历到视图树结构的根节点...所以本质上通过反射,或者在 ViewRootImpl 未初始化前,都是可以在子线程刷新 UI 。这也是为何在 Activity.onCreate 方法中可以子线程刷新 UI 不会崩溃的原因。...从不搞所谓的偏方技术,所以很明显的结果的就是国外大厂的产品在稳定性,隐私性,能耗比等都比国内的流氓生态圈高几个层次。
领取专属 10元无门槛券
手把手带您无忧上云