views.说明在错误的线程更新UI。...Android中相关的view和控件操作都不是线程安全的,所以Android才会禁止在非UI线程更新UI,对于显式的非法操作,比如说直接在Activity里创建子线程,然后直接在子线程中操作UI等,Android...its views便是一个例子,字面意思是只有创建视图层次结构的原始线程才能操作它的View,明显是线程安全相关的。...总结点: 不能在主线程(UI线程)进行耗时的操作,比如连接网络,拷贝大数据,睡眠等操作。 比如连接谷歌网络。...在4.0之后谷歌强制要求连接网络不能在主线程进行访问 只有主线程(UI线程)才可以更新UI
view Android中相关的view和控件操作都不是线程安全的,所以Android才会禁止在非UI线程更新UI,对于显式的非法操作,比如说直接在Activity里创建子线程,然后直接在子线程中操作...its views便是一个例子,字面意思是只有创建视图层次结构的原始线程才能操作它的View,明显是线程安全相关的。...s.说明在错误的线程更新UI。 总结点: 不能在主线程(UI线程)进行耗时的操作,比如连接网络,拷贝大数据,睡眠等操作。 比如连接谷歌网络。...在4.0之后谷歌强制要求连接网络不能在主线程进行访问 只有主线程(UI线程)才可以更新UI 定时代码如下 MainActivity .java import android.os.Bundle; import...// 一旦计时器被终止,它的执行线程就会顺利地终止,并且不会再安排任务了。
先看看崩溃日志: 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...//过滤掉一些非关键代码 view.assignParent(this); } 答案很明显,我们再延伸一下, ViewRootImpl 是通过 WindowManager 实例化的,它的实现类是...H Handler实例是核心中的核心,关键中的关键,一句话,我们的所有消息都需要通过它的处理分发,Activity 的生命周期、用户的触碰事件,一切的反馈都是通过这个来交互,如果没有这个,应用就会像一个...= Thread.currentThread()) { 4746 throw new CalledFromWrongThreadException( // 只有创建视图层次结构的原始线程才能访问它的视图...setText 方法吗,当 mLayout 不为空时才会进入,而事实上只有 View 在 测量 方法里才会对这个值进行赋值,答案也就很明显了,当我们在子线程里 setText 的时候,其实只是简单的设置了这个控件要显示的值
我们从一个异常说起: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created...private void handleAddWindow() { //子线程创建window,只能由这个子线程访问 window的view Button button...,然后添加了一个系统window,window中只有一个button。...翻译就是说 只有创建了view树的线程,才能访问它的子view。并没有说子线程一定不能访问UI。...另外注意2,在activity的onCreate到首次onResume的时期,创建子线程在其中更新UI也是可以的。这不是违背上面的结论了吗?
在 Android Studio 4.0 中,新的 Motion Editor 让这个 API 用起来更方便。它提供了用于创建、编辑和预览 MotionLayout 动画的强大界面。...你用不着再创建和修改复杂的 XML 文件,Motion Editor 会为你生成它们,并支持约束集合、过渡、关键帧和视图属性的编辑。如果你想查看编辑器创建的代码,只需点一下即可。...在 Motion 编辑器中创建、编辑和预览动画 升级的 Layout Inspector 想要调查特定属性的值的源头?或者想通过嵌套视图的实时 3D 表示,更轻松地检查视图层次?...部署到运行 API 29 或更高版本的设备还能获得其他特性,例如动态布局层次结构(随视图更改而更新)、详细的视图属性(还可以帮助你确定资源值是如何解析的)以及正在运行的应用 UI 的 3D 模型。...项目结构)对话框提供支持。
声明式 UI,通过对比可以看到 Kotin DSL 有诸多好处: 有着近似 XML 的结构化表现力 较少的字符串,更多的强类型,更安全 可提取 linearLayoutParams 这样的对象方便复用...另外 Compose 里的代码基本都是可以被混淆的,所以开启混淆之后代码的压缩率也很高。 手动操纵视图会提高出错的可能性。如果一条数据在多个位置呈现,很容易忘记更新显示它的某个视图。...它允许您在应用程序中创建水平滑动的页面布局,类似于 ViewPager 或 RecyclerView。...它控制了视图在屏幕上的显示顺序。具有较高 zIndex 值的视图将显示在具有较低 zIndex 值的视图之上。 默认情况下,视图的 zIndex 值为0。...副作用操作通常包括异步任务、网络请求、数据库操作或其他可能会阻塞主线程的操作。 LaunchedEffect 函数是一个协程构建器,它接受一个或多个参数,并在代码块中执行异步操作。
从创建文件,到编辑约束设置、转场动画、关键帧以及视图属性,Motion Editor 都会为您代劳,再也无需手动创建和编辑复杂的 XML 文件——当然如果您的确需要查看的话,也只需要轻点一下鼠标即可。...全新的 Layout Inspector 就可以帮您轻松做到。它提供的数据会与正在运行的应用完全同步,更会让您对各个资源在应用中如何排布和计算一览无余,使得 UI 调试变得更加简单直观。...如果您的应用是部署到 API 等级 29 或以上的设备,则可以使用到更丰富的功能,比如随着视图变化动态更新的布局层次结构、帮助您更好了解资源取值解析的详细视图属性信息、以及可以展示运行时 UI 结构的实时...您可以尽情在应用中导航、触发动画和视图转场,在这同时依然能精确调试 UI,让每一个像素都尽如人意。前往《Android Studio 4.0+ 中新的 UI 层次结构调试工具》了解更多。...我们还重新设计了 System Trace 界面,用不同的颜色来区分显示事件,从而在视觉上更加醒目。在线程排序方面,更繁忙的线程会优先展示,帮助您专注于所选线程中的数据。
这个问题的根本原因可以简述为:不可控的动效冲突(业务随机性) + 无从安置的主线程耗时方法(弹窗实例化、视图infalte)。 因此我们要寻求一个方案来解决动效冲突导致的卡顿问题。...3.2 CalledFromWrongThreadException来自哪里 众所周知,我们在更新界面元素时,若不在主线程执行,系统会抛CalledFromWrongThreadException,观察异常堆栈...仅在view被attach至window时,它才会作为UI的一部分(挂载至ViewTree),需要被固定线程进行控制、更新等管理操作。...我们能否有多个UI线程? 要回到这个问题,我们还是要回归CalledFromWrongThreadException的由来。...Activity的使用必须在主线程,因为其创建等操作中使用的Handler也被强制指定为mainThreadHandler。
为 Java 开发者准备的 Kotlin 教程 Kotlin 之所以在 Android 开发者中如此流行,首先是因为它是一种很好的语言,同样值得一提的是它与 Java 语言的强大互操作性。...在深受困扰的开发者们看来,Android 开发中不断出现的样板代码中最恼人的就是 findViewById()。每当您要引用层次结构中的视图时,都必须使用正确的视图 ID,并重复输入类型信息。...,这种做法的本质是,在与布局文件关联的绑定对象中为视图创建变量。...它的工作方式与数据绑定类似,但是不需要专门的数据资源文件,而只需使用普通的 XML 布局文件即可。 视图绑定从 Android Studio 3.6 Canary 11 可以开始体验。...但如果您是刚接触外部文件存储的话,阅读文档里的说明可能会需要多花费一些精力,我们也会努力迭代文档以让内容更加易懂。
安卓编程初学者手册中文第三版 零、前言 一、初学安卓和 Java 二、第一次接触:Java、XML 和 UI 设计师 三、探索 AndroidStudio 和项目结构 四、布局和材质设计入门 五、卡片视图和滚动视图的漂亮布局...二十八、临别赠言 Kotlin 安卓编程初学者手册 零、前言 一、安卓和 Kotlin 入门 二、Kotlin、XML 和用户界面设计器 三、探索 AndroidStudio 和项目结构 四、布局和材质设计入门...五、卡片视图和滚动视图的漂亮布局 六、安卓的生命周期 七、Kotlin 变量、运算符和表达式 八、Kotlin 决策和循环 九、Kotlin 函数 十、面向对象编程 十一、Kotlin 的继承 十二、...二十七、安卓数据库 二十八、临别赠言 如何使用 Kotlin 构建安卓应用 零、前言 一、创建您的第一个应用 二、构建用户屏幕流 三、用片段开发用户界面 四、构建应用导航 五、基本库:RetroFit...安卓增强现实应用开发 零、前言 一、增强现实概念和工具 二、观察世界 三、叠加世界 四、定位世界 五、与好莱坞相同——实物上的虚拟 六、让它具有互动性——创造用户体验 七、深入阅读和提示 Android
比如在修改某个view的显示时,调用invalidate()才能看到重新绘制的界面。invalidate()的调用是把之前的旧的view从主UI线程队列中pop掉。...postInvalidate()函数来实现视图的更新 使用postInvalidate则比较简单,不需要handler,直接在线程中调用postInvalidate即可。...这时候你需要创建一个继承了android.os.Handler的子类,并重写handleMessage(Message msg)方法。...也就是说:在新线程创建并发送一个Message,然后再主线程中捕获、处理该消息。 3.使用多线程和双缓冲 Android中SurfaceView是View的子类,她同时也实现了双缓冲。...直接在R.java中去找 3.实现自己的自定义Adapter需要去继承BASEAdapter的,BaseAdapter是没有做任何数据的处理,所以你需要重载它的四个函数 @Override public
在 Android Studio 4.0 中,新的 Motion Editor 让这个 API 用起来更方便。它提供了用于创建、编辑和预览 MotionLayout 动画的强大界面。...你用不着再创建和修改复杂的 XML 文件,Motion Editor 会为你生成它们,并支持约束集合、过渡、关键帧和视图属性的编辑。如果你想查看编辑器创建的代码,只需点一下即可。...或者想通过嵌套视图的实时 3D 表示,更轻松地检查视图层次?借助新的 Layout Inspector,你可以获得正在运行的应用中的最新数据,并获得关于资源解析的深度信息,从而更直观地调试 UI。...部署到运行 API 29 或更高版本的设备还能获得其他特性,例如动态布局层次结构(随视图更改而更新)、详细的视图属性(还可以帮助你确定资源值是如何解析的)以及正在运行的应用 UI 的 3D 模型。...项目结构)对话框提供支持。
Zygote 进程在系统启动时创建,它预加载了许多常用的类和资源,为应用程序进程提供了一个初始化好的运行环境。当需要创建新的应用程序进程时,系统会通过 Zygote 进程来 fork 出新的进程。...资源共享:由于 Zygote 进程预加载的类和资源在内存中只有一份,它们可以被所有应用程序进程共享。这样可以减少系统的内存占用,提高资源利用率。...如果只是视图内容的变化,应优先使用invalidate()方法;如果是视图布局参数的变化,需要使用requestLayout()方法。View 的更新必须在主线程吗?...任何线程都可以更新自己创建的 UI,只需要满足以下两种情况在 ViewRootImpl 创建之前,可以在子线程更新 UI,比如在 Activity onCreate 的时候在 ViewRootImpl...创建之后,只需要保证创建 ViewRootImpl 的线程和更新 UI 的线程是同一个就可以;比如我们在子线程调用 ViewManager#addView我们同上说子线程不可以更新 UI,这个异常是在
导语: 在测试流畅度的过程中,必不可免的要与FPS,Jank等指标接触,但为了加深理解,今天来简单扒一扒安卓的渲染原理; PerfDog使用Jank作为来代表游戏流畅度的指标,详情可以看 APP&游戏需要关注...View)元素,这些元素是以树形结构来组织,最终构成所谓视图树的结构; 在绘制一个Android应用程序窗口的UI之前,要确定它里面的各个子View元素在父元素里面的大小以及位置。...,注意绘制View层次结构这些操作是在图形缓冲区中绘制完成的; 此时就要把这个图形缓冲区被交给SurfaceFlinger服务 SurfaceFlinger服务概述: SurfaceFlinger...),在SurfaceFlinger服务启动的过程中会自动创建两个线程:其中一个线程用于监控控制台事件,另外一个线程则用于渲染系统的UI; Android应用程序为了能够将自己的UI绘制在系统的帧缓冲区上...简单来说就是当Android应用层在图形缓冲区中绘制好View层次结构后,应用层通过Binder机制与SurfaceFlinger通信并借助一块匿名共享内存会把这个图形缓冲区会被交给SurfaceFlinger
从历史上看,Android 的视图层次结构一直被描述为 UI 组件树。随着 app 状态的变化,需要更新 UI 层次结构来显示当前的数据。...这不仅乏味繁琐,而且手动更新视图也会增加出错的可能性 (例如忘记更新视图)。...当基础数据发生变化时,Compose 框架会自动为您更新 UI 层次结构,从而使您可以轻松快速的构建 UI。...可以通过以下两种主要的方式将 Compose 与基于视图的 UI 结合起来: 您可以添加 Compose 元素到现有的 UI,或者创建一个全新的基于 Compose 的屏幕,或者是向现有的 fragment...Android Studio 会创建一个新的 Activity,其中包含由将该功能所生成的 UI,并将其部署到您在设备上的应用。
就是管理数据的地方,SurfaceView就是展示数据的地方,只有通过SurfaceView才能展现Surface中的数据。...Surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。...SurfaceView 的优缺点 一般的Activity包含的多个View会组成View hierachy的树形结构,只有最顶层的DectorView才是对WMS可见的,这个DecorView在WMS中有一个对应的...所以它的优点就是可以在独立的线程中绘制,不影响主线程,而且使用双缓冲机制,播放视频时画面更顺畅。...当客户端使用 TextureView 呈现内容时,界面工具包会使用 GPU 将 TextureView 的内容合成到 View 层次结构中。
重要提示:更新后,需要重新启动 Android Studio 才能应用从早期版本的 IDE 迁移的所有内存设置。有关更多信息,请参见“已知问题”页面。...image 现在事件采用了独特的颜色,以便于区分。 线程按它们中的跟踪事件数进行排序,以便 “busier” 的线程在列表中排名更高。 可以选择一个或多个线程以仅在那些选定的线程的右列中查看分析。...除了现有布局检查器的许多相同功能外,实时布局检查器还包括: Dynamic layout hierarchy(动态布局层次结构):随着设备视图的更改而更新。 ?...image 3D view(3D视图):在运行时通过高级 3D 可视化查看应用程序的视图层次结构,要使用此功能,只需在 Layout Inspector 窗口中单击布局并旋转它。 ?...image 六、Kotlin Android实时模板 Android Studio 现在包括适用于 Kotlin 类的Android 实时模板。
随着用户的下拉或者上拉手势,已经被回收的列表项要重新加载到界面上,倘若每次加载都得从头创建视图对象,势必增加了系统的资源开销。...根据这种设计思路,提取出了循环视图基础适配器,它的Kotlin代码如下所示: //循环视图基础适配器 abstract class RecyclerBaseAdapter视图的网格适配器,它实现了类似淘宝主页的网格频道栏目,具体的Kotlin代码如下所示: //把公共属性和公共方法剥离到基类RecyclerBaseAdapter, //此处仅需实现getItemCount...对于第一个的布局编码,可以考虑将其作为一个整型的输入参数;对于第二个的数据结构,可以考虑定义一个模板类,在外部调用时再指定具体的数据类;对于第三个的bind方法,若是Java编码早已束手无策,现用Kotlin...尤其是最后的两种实现方式,分别运用了Kotlin的多项综合技术,才能集Kotlin精妙语法之大成。 点此查看Kotlin入门教程的完整目录