Handler也是个磨人的小妖精,一次又一次的败给她 一、还是以最经典的:子线程更新UI来引入吧 场景:点击按钮新建线程,在新线程里更改TextView的值,如下图 handler1.png...;//更改视图 } }.start(); } } 2.结果: 结果.png 看起来不太好,直接崩了,报了个CalledFromWrongThreadException...:只有创建视图层的那个原始线程(main)才给摸他的视图。...是啊,我穿(main线程)的衣服(View)凭什么给你(其他线程)乱摸(修改...),你又不是我女朋友。...二、Handler的使用 人家(其他线程)就是看你衣服上有个米粒,想把他拿掉,你(main线程)还不乐意了。
(DOM是一种文档对象模型,他的层次结构是除了顶级元素,所有元素都被包括到另外的元素节点中,有点像家谱树结构,很典型的就是html代码解析) 到这里,一个有完整view结构的DecorView就创建出来了...currentThread不是mThread的时候,就会崩溃,报的错误是 “只有创建视图层次结构的原始线程才能触摸它的视图” ,看到这里是不是猜到一些了,这个mThread难道就是“创建视图的原始线程”...所以我们就可以得知崩溃的真正原因,就是当前线程不是ViewRootImpl创建时候的线程就会崩溃。...翻译的还是比较准确的,只有创建视图的原始线程才能修改这个视图,听起来也蛮有道理的,我创造了你才有权利改变你,有那味了。...其中的关键就是view被绘制到界面时候的线程(也就是最顶层ViewRootImpl被创建时候的线程)和进行UI更新时候的线程是不是同一个线程,如果不是就会报错。
ViewRootImpl 是在哪里实例化的,作为单线程模型,我们可以从 应用的 Java 层入口,ActivityThread 也就是 UI 线程的实现类去查看 1131 private class...= Thread.currentThread()) { 4746 throw new CalledFromWrongThreadException( // 只有创建视图层次结构的原始线程才能访问它的视图...setText 方法吗,当 mLayout 不为空时才会进入,而事实上只有 View 在 测量 方法里才会对这个值进行赋值,答案也就很明显了,当我们在子线程里 setText 的时候,其实只是简单的设置了这个控件要显示的值...,并不会立即去显示,因为 mLayout 是为空,为什么为空,因为只有在 Activity 的onResume 生命周期里才会去实例化 ViewRootImpl 一个个方法栈的调用最后才会触发 View...最后扩展一下,如果就是想在子线程里更新 UI 怎么办呢,在onResume 之前就行,或者把 View 的 ViewRootImpl 实例化放到子线程来进行,这样就不会因为非 UI 线程抛出异常。
资源共享:由于 Zygote 进程预加载的类和资源在内存中只有一份,它们可以被所有应用程序进程共享。这样可以减少系统的内存占用,提高资源利用率。...invalidate()用于更新视图的内容,只会触发视图的绘制流程,性能开销较小。在实际开发过程中,需要根据视图的变化情况选择合适的方法来更新视图。...如果只是视图内容的变化,应优先使用invalidate()方法;如果是视图布局参数的变化,需要使用requestLayout()方法。View 的更新必须在主线程吗?...任何线程都可以更新自己创建的 UI,只需要满足以下两种情况在 ViewRootImpl 创建之前,可以在子线程更新 UI,比如在 Activity onCreate 的时候在 ViewRootImpl...创建之后,只需要保证创建 ViewRootImpl 的线程和更新 UI 的线程是同一个就可以;比如我们在子线程调用 ViewManager#addView我们同上说子线程不可以更新 UI,这个异常是在
String path = et_path.getText().toString().trim(); // 2.2创建URL对象,指定我们要访问的网址(路径)...Android中相关的view和控件操作都不是线程安全的,所以Android才会禁止在非UI线程更新UI,对于显式的非法操作,比如说直接在Activity里创建子线程,然后直接在子线程中操作UI等,Android...its views便是一个例子,字面意思是只有创建视图层次结构的原始线程才能操作它的View,明显是线程安全相关的。...总结点: 不能在主线程(UI线程)进行耗时的操作,比如连接网络,拷贝大数据,睡眠等操作。 比如连接谷歌网络。...在4.0之后谷歌强制要求连接网络不能在主线程进行访问 只有主线程(UI线程)才可以更新UI
比如在修改某个view的显示时,调用invalidate()才能看到重新绘制的界面。invalidate()的调用是把之前的旧的view从主UI线程队列中pop掉。...postInvalidate()函数来实现视图的更新 使用postInvalidate则比较简单,不需要handler,直接在线程中调用postInvalidate即可。...这时候你需要创建一个继承了android.os.Handler的子类,并重写handleMessage(Message msg)方法。...也就是说:在新线程创建并发送一个Message,然后再主线程中捕获、处理该消息。 3.使用多线程和双缓冲 Android中SurfaceView是View的子类,她同时也实现了双缓冲。...,它是负责刷新ListView的列表的 4.关于视图View的很多知识这里简单讲不完,以后有机会碰到了慢慢来学习了
这个问题的根本原因可以简述为:不可控的动效冲突(业务随机性) + 无从安置的主线程耗时方法(弹窗实例化、视图infalte)。 因此我们要寻求一个方案来解决动效冲突导致的卡顿问题。...3.2 CalledFromWrongThreadException来自哪里 众所周知,我们在更新界面元素时,若不在主线程执行,系统会抛CalledFromWrongThreadException,观察异常堆栈...mViewRootImpl = viewRootImpl; // ... } } 正如注释描述,结合源码观察,mAttachInfo赋值时刻确实只有view的attach与detach...我们能否有多个UI线程? 要回到这个问题,我们还是要回归CalledFromWrongThreadException的由来。...Activity的使用必须在主线程,因为其创建等操作中使用的Handler也被强制指定为mainThreadHandler。
SingleInstance:系统会为它创建一个单独的任务栈,并且这个实例独立运行在一个 task中,这个task只有这个实例,不允许有别的Activity 存在(可以理解为手机内只有一个)。...onDestroyView():当Fragment的UI从视图结构中移除时调用。 onDestroy():销毁Fragment时调用。...newArray(int size):创建指定长度的原始对象数组。 User(Parcel in) 从序列化后的对象中创建原始对象。...Looper:消息泵,是 MessageQueue 的管理者,会不断从 MessageQueue 中取出消息,并将消息分给对应的 Handler 处理,每个线程只有一个 Looper。...Handler 创建的时候会采用当前线程的 Looper 来构造消息循环系统,需要注意的是,线程默认是没有 Looper 的,直接使用 Handler 会报错,如果需要使用 Handler 就必须为线程创建
,所以Android才会禁止在非UI线程更新UI,对于显式的非法操作,比如说直接在Activity里创建子线程,然后直接在子线程中操作UI等,Android会直接异常退出,并提示should run on...its views便是一个例子,字面意思是只有创建视图层次结构的原始线程才能操作它的View,明显是线程安全相关的。...s.说明在错误的线程更新UI。 总结点: 不能在主线程(UI线程)进行耗时的操作,比如连接网络,拷贝大数据,睡眠等操作。 比如连接谷歌网络。...在4.0之后谷歌强制要求连接网络不能在主线程进行访问 只有主线程(UI线程)才可以更新UI 定时代码如下 MainActivity .java import android.os.Bundle; import...// 一旦计时器被终止,它的执行线程就会顺利地终止,并且不会再安排任务了。
调用更容易被视为视图,因为它将多个函数调用合并到单个项中。然而,尚不清楚它们是否都具有相同的处理时间,还是只有其中一个处理时间较长。...在这种情况下,Raw Hierarchy原始层次结构视图在本例中使用。Raw Hierarchy视图与Hierarchy视图的不同之处在于Calls总是固定为1。...Tips 当打开一个项目时,通常会有一个很深的层次结构。在这种情况下,您可以通过按住Mac上的Option键(Windows上的Alt键)打开层次结构的所有级别。...相反,按住键关闭一个项目将关闭该层次结构下的所有内容 timeline view 在时间轴视图中,层次视图中的项目显示为方框,因此在查看整个视图时,您可以直观地看到加载的位置。...因为它是鼠标可访问的,即使是深层的层次结构也可以通过拖动来掌握。此外,有了时间线,就不需要切换线程;显示所有线程。这样就可以很容易地看到每个线程中什么时候发生了什么类型的处理。
用这些组合来构建属于你的人机交互,而不是只用一个视图显示所有的内容,你通常需要几个视图来构建视图层次。视图层次中的每个视图都是你所构建用户交互中特定的一部分,并通常为特殊类型内容所优化的(各司其职)。...例如,UIKit就有用以显示文本、图片和其他类型内容的特定视图。 相关章节:视图和窗口结构、视图 窗口可协调视图的显示#### 窗口是UIWindow的实例用以呈现整个应用的用户交互。...窗口用视图(视图控制器)管理与可视化视图层次的交互和改变。大多数,应用的窗口从不发生改变,窗口一旦创建便保持不变,只有在窗口上的视图发生变化。每个应用至少有一个窗口用以呈现设备主屏幕上的用户交互。...如果有外置屏幕接入设备,应用会创建第二个窗口显示相应的内容。 相关章节:窗口 动画可提供用户人机交互的反馈#### 动画可以将视图层次的改变可视化反馈给用户。...使用Interface Builder,你会将你的视图存放在nib文件中,这种文件是一种存储视图和其他对象原始版本关系的资源文件,一旦在runtime中加载nib文件,nib文件中的对象就会重新组成可代码操作的具体对象
4.使用Android中的消息机制解决:Only the original thread that created a view hierarchy can touch its views 原始代码 public...ERROR/AndroidRuntime(421): FATAL EXCEPTION: Thread-8 ERROR/AndroidRuntime(421): android.view.ViewRoot$CalledFromWrongThreadException...原因在于,Android系统中的视图组件并不是线程安全的,如果要更新视图,必须在主线程中更新,不可以在子线程中执行更新的操作。...,把复杂的任务处理工作交给子线程去完成,然后子线程通过handler对象告知主线程,由主线程更新视图,这个过程中消息机制起着重要的作用。...Android的消息循环是针对线程的,每个线程都可以有自己的消息队列和消息循环。
用这些组合来构建属于你的人机交互,而不是只用一个视图显示所有的内容,你通常需要几个视图来构建视图层次。视图层次中的每个视图都是你所构建用户交互中特定的一部分,并通常为特殊类型内容所优化的(各司其职)。...例如,UIKit就有用以显示文本、图片和其他类型内容的特定视图。 相关章节:视图和窗口结构、视图 窗口可协调视图的显示 窗口是UIWindow的实例用以呈现整个应用的用户交互。...窗口用视图(视图控制器)管理与可视化视图层次的交互和改变。大多数,应用的窗口从不发生改变,窗口一旦创建便保持不变,只有在窗口上的视图发生变化。每个应用至少有一个窗口用以呈现设备主屏幕上的用户交互。...如果有外置屏幕接入设备,应用会创建第二个窗口显示相应的内容。 相关章节:窗口 动画可提供用户人机交互的反馈 动画可以将视图层次的改变可视化反馈给用户。...使用Interface Builder,你会将你的视图存放在nib文件中,这种文件是一种存储视图和其他对象原始版本关系的资源文件,一旦在runtime中加载nib文件,nib文件中的对象就会重新组成可代码操作的具体对象
Surface是一个用来画图形的地方,但是我们知道画图都是在一个Canvas对象上面进行的,Surface中的Canvas成员,是专门用于提供画图的地方,就像黑板一样,其中的原始缓冲区是用来保存数据的地方..., Surface本身的作用类似一个句柄,得到了这个句柄就可以得到其中的Canvas、原始缓冲区以及其他方面的内容,所以简单的说Surface是用来管理数据的(句柄)。...VISIBLE : GONE, mContentInsets); } 很明显,每个SurfaceView创建的时候都会创建一个MyWindow,new MyWindow(this)中的this正是...就是管理数据的地方, SurfaceView就是展示数据的地方,只有通过SurfaceView才能展现Surface中的数据。...SurfaceView的优缺点: 一般的Activity包含的多个View会组成View hierachy的树形结构,只有最顶层的DectorView才是对WMS可见的,这个DecorView在WMS中有一个对应的
,使用图层来创建复杂的编程接口 轻量化的数据结构,它可以同时显示让上百个图层产生动画效果 一套非常较简单的动画接口,能让动画运行在独立的线程中,并可以独立于主线程之外....一旦动画配置完成并启动,核心动画就能独立并完全控制相应的动画帧. 提高应用性能.应用程序只有当发生改变的时候才会重绘内容....)里面.Core Animation Class hierarchy (核心动画类层次结构图如下)....在Core Animation的类层次结构图中,可以发现图层类(LayerClasses) 是Core Animation 的核心基础....CALayer 是整个图层类的基础,它是所有核心动画图层类的父类. 和UIView 一样,CALayer 也是有自己的父图层类,以及同样拥有子图层类的集合. 它构成了一个图层树的层次结构.
在构造方法中赋值时,需通过 _ 下划线访问 @State 的原始值并进行赋值。...@State 是线程的安全,可以在非主线程中进行修改。...引入 @StateObject 意味着所有相关操作都在主线程上进行( SwiftUI 会隐式为视图添加 @MainActor),包括异步操作。应将需要在非主线程上运行的代码应该从视图代码中剥离。...通常情况下,会有多个视图从不同层级观察并响应同一个实例,必须合理优化才能避免应用性能劣化。这也是很多开发者不喜欢 @EnviromentObject 的原因。...在一个视图层次中,同一个类型的环境对象只有一个实例有效。
,也来维护和管理下一个视图控制器的延迟加载时机,这种情况下我们无法“插手”视图控制器的延迟加载。...l 将文件读写访问从主线程中剥离出来,由一个子线程负责。 l 写入应该采用增量方式,每次只写入变化的部分,不要为改变几个字节 l 写入整个文件。...3.1.1 文件结构优化 文件要保存数据,应该是结构化的,苹果中的plist文件就是很好的结构化文件。plist文件结构是层次模型的树形结构,层次的深浅会影响读取/写入的速度。...3.2.2 查询优化 3.2.2.1 索引 索引能够提供查询性能,哪些字段需要创建索引很关键,这些字段只有在表连接或where条件子句中使用才能提供查询性能;在INTEGER PRIMARY...对象,如果没有可重用的UITableViewHeaderFooterView对象,则使用initWithReuseIdentifier:构造方法创建。
Surface本身的作用类似一个句柄,得到了这个句柄就可以得到其中的Canvas、原始缓冲区以及其他方面的内容,所以简单的说Surface是用来管理数据的(句柄)。...就是管理数据的地方,SurfaceView就是展示数据的地方,只有通过SurfaceView才能展现Surface中的数据。...Surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。...SurfaceView 的优缺点 一般的Activity包含的多个View会组成View hierachy的树形结构,只有最顶层的DectorView才是对WMS可见的,这个DecorView在WMS中有一个对应的...当客户端使用 TextureView 呈现内容时,界面工具包会使用 GPU 将 TextureView 的内容合成到 View 层次结构中。
△ 栏式网格 您可以通过这些栏将屏幕划分为不同区域,用于容纳相关的信息和操作,进而改善信息层次结构。...△ 使用栏式网格将屏幕划分为三个主要区域 在本例中,三个主要区域通过重排来保持相同的信息层次结构,但以更加人性化的方式在小屏幕上显示。...因此我们定义了新断点值,这有助于将设备划分到预设的尺寸类别中,这些尺寸代表了市场上实际设备的尺寸。它们有助于将应用版面的原始尺寸转换为离散的标准化组,您可以据此做出更高层次的界面决策。...△ 主页横幅 规范布局实践 采用响应式界面不仅仅是为不同屏幕尺寸提供并行结构,应用还要足够灵活,这样才能根据各种需要调整尺寸,例如旋转设备、多窗口模式以及折叠和非折叠姿态。...我们将使用这些坐标以及宽度和高度创建一个 Rect 对象,这样我们便得到了窗口坐标空间中的视图边界。
可读性:XML的语法相对直观和易读,可以被人类读取和理解。而XAML的语法相对复杂,需要一定的学习和理解才能读取和理解。 功能:XML主要用于描述数据和结构,它没有直接的编程功能。...MVVM 的特性列表 清晰的分层结构:MVVM模式将应用程序分为模型、视图和视图模型三个层次,使得代码的组织结构更加清晰明了,易于理解和维护。...可视化树是由UI元素(如窗口、面板、控件等)组成的层次结构,每个UI元素都有一个父元素和零个或多个子元素。这种层次结构描述了UI元素之间的布局和渲染关系。...当我们在XAML中定义UI界面时,实际上是在创建可视化树。WPF框架会根据可视化树来确定UI元素的位置和大小,并将它们渲染到屏幕上。 逻辑树是另一个层次结构,它描述了UI元素之间的逻辑关系。...在WPF应用程序中,可以使用多个线程来执行不同的任务,但是只有UI线程可以访问和修改UI元素,通过Dispatchers可以将工作项调度到UI线程上执行,以确保线程安全。 38.
领取专属 10元无门槛券
手把手带您无忧上云