背景 现在安卓系统无论是性能还是体验上其实都不输于iOS,只是因为手机厂商多而杂,他们会改源码,自定义系统,最后又过一遍不同开发水平工程师的手,导致很多手机即使在机器上面的跑分非常高,里面的APP运行也有卡顿现象...性能优化的目的 流畅(解决:卡顿) 稳定(解决:内存溢出、崩溃) 低耗损(解决:耗电快、流量大、网络慢) 小安装包(解决:APK过大) 性能优化的方向 布局优化 绘制优化 网络优化 APK优化 内存优化...常用方案: 优先选择LinearLayout布局可以减少View的层级(注意相同组件可能RelativeLayout绘制时间长); 使用 标签抽取常用的布局组件中的共同部分(便于复用...; 删除控件中无用的属性; 布局复用.比如listView 布局复用 尽量避免过度绘制(overdraw),比如:背景经常容易造成过度绘制。...由于我们布局设置了背景,同时用到的MaterialDesign的主题会默认给一个背景。这时应该把主题添加的背景去掉;还有移除 XML 中非必须的背景 自定义View优化。
,启动速度较慢(感官上)的应用可能导致用户再次开启App的意图下降,或者卸载放弃该应用程序。...视觉优化 应用程序启动有三种状态,每种状态都会影响应用程序对用户可见所需的时间:冷启动,热启动和温启动。 在冷启动时,应用程序从头开始。在其他状态下,系统需要将正在运行的应用程序从后台运行到前台。...我们建议您始终根据冷启动的假设进行优化。这样做也可以改善热启动和温启动的性能。 在冷启动开始时,系统有三个任务。这些任务是: 加载并启动应用程序。 启动后立即显示应用程序空白的启动窗口。...在屏幕上执行View的绘制过程.measure -> layout -> draw 应用程序进程完成第一次绘制后,系统进程会交换当前显示的背景窗口,将其替换为主活动。...查找Overdraw Overdraw(过度绘制)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。
流畅度评测指标FPS--->SM 对于流畅度的评测,大家第一时间会想到FPS。当前业界衡量一个APP是否流畅的主要指标就是FPS。...另外如果屏幕根本没有绘制需求,画面是静止的,那FPS就是0。 2)屏幕上显示的每一帧合成都是针对手机里的所有进程的,所以即使APP停止了绘制,手机里其他的进程可能还在绘制。...从UI层优化入手 GPU 过度绘制+Trace for OpenGL 过度绘制:在屏幕一个像素上绘制多次,比如一个TextView后有背景,那么显示文本的像素至少绘制两次,一次是背景,一次是文本。...Time/Call和Call+Recur Calls/Total值都不大,在滑动过程中cpu占用的时间分配比较合理,基本上都是主线程用。...我们在测试的时候,可以用上面讲到的一些方法和工具处理并修复应用中的流畅度问题,确保我们提供的应用程序能够给用户提供优良的渲染性能,实现了平滑流畅的60FPS。 李敏 享米测试工程师
在理想情况下,60 FPS 就感觉不到卡,这意味着每个绘制时长应该在16 ms 左右。如果某个操作花费的时间是 24ms ,系统在得到 VSYNC 信号时就无法正常进行正常渲染,这样就发生了丢帧现象。...所以在绘制时要注意两点: 1 .onDraw中不要创建新的局部对象。 onDraw方法中不要做耗时的任务。...在冷启动开始时,系统有三个任务。...此时至此启动完成,用户可以使用程序(app)了,那么这里就会有两类创建: Application的创建 当Application启动时,会有一个空白的启动窗口保留在屏幕上,直到系统首次完成绘制应用程序...你比如,我用户Back退出应用程序,然后又重新启动,应用程序会再次执行Activity的onCreate(),但会从Bundle(savedInstanceState)获取数据,我们平时应用成勋崩溃,不也是通过该方法保存数据的吗
三三想成为安卓糕手 一:TextView的常见属性 1:引入 TextView:文本显示控件,基于TextView还有很多子类,都与文本处理有关...必须设置排列方向 android:gravity="center" //视图居中 android:orientation="vertical" //垂直的 //这两句代码是在LinearLayout...在文本中添加图片 (1)xml中使用drawable android:drawableLeft="@mipmap/ic_launcher_round"//在文本当中添加图片,并放在左边...(2)java中使用drawable ①方法理解 setCompoundDrawablesRelativeWithIntrinsicBounds() 在固有的边界上设置复合的drawable Compound...复合的 Drawable 可绘制的对象 intrinsic 固有的 ②参数理解 自己理解,传四个参数,设置左,上,右,下都用什么图片(实参可为null) 大白话:在固定边界上设置复合的图标
Windows操作系统中的图形界面,它也帮助开发人员在不考虑特定设备细节的情形下在计算机上进行绘图操作。...比如就图形输出来说,开发人员在绘图时根本不用考虑是在屏幕上绘制还是在打印机上绘制,只需要指明输出设备即可让GDI自己解决这些细节问题。...GDI+构成了Windows XP操作系统及其后续版本的子系统的应用程序编程接口(API)。GDI+负责在屏幕和打印机上显示信息,它是GDI的改进,同时也是.NET框架结构的重要组成部分。...和GDI一样,它提供了对二维图形图像和文字排版处理的支持,通过GDI+能够创建与设备无关的应用程序。使用GDI+可以创建图形、绘制文本以及将图形图像作为对象来操作,旨在提高性能和易用性。...PNG文件可包含灰度校正和颜色校正信息,以便图像在各种各样的显示设备上精确地呈现。 ◇标签图像文件格式(TIFF) TIFF是一种灵活的、可扩展的格式,各种各样的平台和图像应用程序都支持这种格式。
本文将告诉你如何让你的应用程序支持各种不同屏幕大小,主要通过以下几种办法: 让你的布局能充分的自适应屏幕 根据屏幕的配置来加载合适的UI布局 确保正确的布局应用在正确的设备屏幕上 提供可以根据屏幕大小自动伸缩的图片...你的应用程序应该不仅仅实现了可自适应的布局,还应该提供一些方案根据屏幕的配置来加载不同的布局,可以通过配置限定符(configuration qualifiers)来实现。...现在有很多的应用程序为了支持大屏设备,都会实现“two pane”模式(程序会在左侧的面板上展示一个包含子项的List,在右侧面板上展示内容)。...然后通过SDK中带有的draw9patch工具打开这张图片(工具位置在SDK的tools目录下),你可以在图片的左边框和上边框绘制来标记哪些区域可以被拉伸。...你也可以在图片的右边框和下边框绘制来标记内容需要放置在哪个区域。结果如下图所示: ? 注意图片边框上的黑色像素,在上边框和左边框的部分表示当图片需要拉伸时就拉伸黑点标记的位置。
过度绘制 在“开发者选项”中打开“调试 GPU 过度绘制”(对未默认开启硬件加速的界面需要同时打开“强制进行 GPU 渲染”)。 无色:没有过度绘制,每个像素绘制了 1 次。...优化方法 合理选择 RelativeLayout/LinearLayout RelativeLayout 层级低,但如果彼此依赖,在确定位置时,会给所有子 View 做一次排序,然后重新测量,因为会引起多次测量...如果布局里自定义了一个全屏的背景,DecorView 的背景无用,但它会产生一次 Overdraw。...自定义 View 本身被认为一层,但是 onDraw 里可绘制时可能产生过度绘制,通过 canvas.clipRect 来解决,具体参见 《Android应用性能优化最佳实践》2.4.3 一节。...SurfaceView 或 TextureView 可以通过将绘图操作移动到另一个单独线程上提高性能。 尽量为所有分辨率创建资源,减少不必要的硬件缩放,这会降低 UI 的绘制速度。
前言 小伙伴们肯定都有在玩儿一些游戏,比如和平精英,在界面上展示的名字,其实就是Android中咱们上一篇介绍到的TextView控件。...> 现在,当用户点击按钮时,Android系统会调用Activity的自定义(视图)方法。...三、按钮样式设置 每个按钮都使用系统的默认按钮背景进行样式化,如果您对默认按钮样式不满意,并且希望对其进行自定义以匹配应用程序的设计,那么您可以用可绘制的状态列表替换按钮的背景图像。...状态列表可绘制是在XML中定义的可绘制资源,它根据按钮的当前状态更改其图像。一旦定义了一个可以用XML绘制的状态列表,就可以将它应用到具有 android:background属性的按钮上。...1.设置背景图 方法一:在xml布局里直接设置背景图 ?
4.在iOS9系统的手机上使用SDWebImage不显示图片,在iOS10、iOS11手机上、模拟器上都是显示的 因为网络请求链接使用的是 https 所以info.plist中就没有设置App Transport...Security Settings 结果使用SDWebImage加载图片 在iOS10、iOS11手机上、模拟器上都是显示的,可是在 iOS9的手机上就是不显示,无奈再次在info.plist中就没有设置...PS: iOS10.3.2 系统下 UITabbar 的点击效果添加了选中背景,这在iOS11和iOS9中是没有的,没注意,当时吓一跳以为是Bug,结果是系统特色。...5. iOS11上 MBProgressHUD 不显示 事情是这样的,iOS11之前的手机上点击提交按钮都会提示“XXXX不能为空”,可是在刚刚更新的iOS11的手机上,点击按钮的时候并没有提示,当时以为是按钮没有触发点击事件...,把第一个取消选中就可以看到崩溃时详细的位置了。
你的应用程序应该不仅仅实现了可自适应的布局,还应该提供一些方案根据屏幕的配置来加载不同的布局,可以通过配置限定符(configuration qualifiers)来实现。...现在有很多的应用程序为了支持大屏设备,都会实现“two pane”模式(程序会在左侧的面板上展示一个包含子项的List,在右侧面板上展示内容)。...例如,7寸的平板最小宽度是600dp,所以如果你想让你的UI在这种屏幕上显示two pane,在更小的屏幕上显示single pane,你可以使用sw600dp来表示你想在600dp以上宽度的屏幕上使用...为了将图片转换成nine-patch图片,你可以从一张普通的图片开始: 然后通过SDK中带有的draw9patch工具打开这张图片(工具位置在SDK的tools目录下),你可以在图片的左边框和上边框绘制来标记哪些区域可以被拉伸...你也可以在图片的右边框和下边框绘制来标记内容需要放置在哪个区域。结果如下图所示: 注意图片边框上的黑色像素,在上边框和左边框的部分表示当图片需要拉伸时就拉伸黑点标记的位置。
Fragment本身占用内存比Activity少很多,在流畅性,性能上具有很大的优势,尤其是在中低端手机上。此外,如果你的应用需要移植到平板上的话,那使用Fragment更是你的不二之选。...,在手机上分屏显示两个内容,在平板上面就可以左右显示两个内容。...您可以将片段视为 Activity 的模块化组成部分,它具有自己的生命周期,能接收自己的输入事件,并且您可以在 Activity 运行时添加或删除片段(有点像您可以在不同 Activity 中重复使用的...对应生命周期可参考下图。...其中大多数程序必须使用Fragments 必须实现的三个回调方法分别为: onCreate 系统创建Fragments 时调用,可做执行初始化工作或者当程序被暂停或停止时用来恢复状态,跟Activity
最基本的UI层显示优化 1.调试GPU过度渲染 在App出现卡顿的时候,我们第一时间会想到我们的App是不是存在过度绘制的问题。...过度绘制指的是在屏幕一个像素上绘制多次(超过一次),例如一个有背景的TextView,那显示文字的那个像素至少绘制了两次,一次是文字,一次是背景。...,设计人员设计的底色,根本不是默认的背景色,如果我们在这个页面的根布局再设一个背景的话就是多绘制一层背景。...另外上面的设置背景代码,要注意书写顺序,这里可包含了不少View的创建的知识,有兴趣的同学可以自行查阅。...流畅度优化经验总结 最后我来总结一下通篇对流畅度优化上的经验: UI布局优化 使用LinearLayout代替RelativeLayout,因为LinearLayout性能上稍微好一点 如果复杂的布局,
第六章 资源管理 本章小结: 1、本单元学习目的 通过了解应用程序常用的各种资源,掌握资源的访问方法,以及两种设置界面外观的方式:样式(Style)和主题(Theme);对于可绘制资源,重点掌握三种Drawable...比如一个有300个像素宽度的按钮,在低分辨率的手机上它可能占据整个屏幕;但是,在高分辨率的手机上可能只占据屏幕的一半。 px是指屏幕中可以显示的最小元素单元,它表示像素(pixel)。...比如:添加一个定制的按钮样式,设置不同的文本颜色和背景颜色。 \res\values\styles.xml 定义好样式以后,就可以在布局文件的按钮定义中使用新的样式。...新的样式实际上包含了两个样式,一个是背景样式,一个是文本样式,背景样式是从CustomButton上继承下来的。...难点 (1) 可绘制资源 Drawable代表了一大类资源。比如:图形、位图图像就是可绘制的资源。
我们在TitleBar标签中添加此前的LinearLayout的属性:android:orientation和android:background。...当ViewStub调用inflate方法或者设置可见时,系统会加载ViewStub指定的布局,然后将这个布局添加到ViewStub中,因此,在对ViewStub调用inflate方法或者设置可见时,它是不占布局空间和系统资源的...同样手机屏幕绘制也是如此,过度绘制是指在屏幕上某个像素在同一帧的时间内被绘制多次,从而浪费了GPU和CPU的资源。产生这一原因主要有两个原因: 在XML布局中,控件有重叠且都有设置背景。...各个颜色的定义为: 原色: 没有过度绘制 – 每个像素在屏幕上绘制了一次。 蓝色: 一次过度绘制 – 每个像素点在屏幕上绘制了两次。 绿色: 两次过度绘制 – 每个像素点在屏幕上绘制了三次。...粉色: 三次过度绘制 – 每个像素点在屏幕上绘制了四次。 红色: 四次或四次以上过度绘制 – 每个像素点在屏幕上绘制了五次或者五次以上。
(1)ImageView缺少src内容 检查Overdraw Overdraw(过度绘制)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。...分析到activity_main.xml的布局文件时,发现这里使用了多个嵌套的LinearLayout布局,而且每个LinearLayout都会使用一次android:background设置一次自己的背景颜色...仔细分析在其中一个嵌套ImageView的LinearLayout布局背景颜色与最外层的背景颜色是一样的,属于不需要的背景色,因此将这个LinearLayout中的android:background属性删除...)设置布局的时候,android会自动填充一个默认的背景,而在这个UI中,我们使用了填充整个app的背景,因此不需要默认背景,取消也很简单,只需要在activity中的onCreate方法中添加这么一句就行了...ui界面的绘制图片,因此我们也在activity中的onCreate方法中添加getWindow().setBackgroundDrawable(null);取消默认绘制。
标题图 UI的描述 对于Android应用程序中,所有用户界面元素都是由View和ViewGroup对象构建的。View是绘制在屏幕上能与用户进行交互的一个对象。...用户界面布局 在你APP软件上的,用户界面上显示的每一个组件都是使用层次结构View和ViewGroup对象来构成的,比如,每个ViewGroup都是不可见容器,每个ViewGroup视图组用于组织子视图...图片 LinearLayout线性布局 常用属性: id:为该组件添加一个资源id orientation:布局中的排列方式,有两种方式: horizontal水平 vertical竖直 layout_width...表示填充父容器 gravity:控制组件所包含的子元素的对齐方式 layout_gravity:控制该组件在父容器里的对齐方式 background:为该组件添加一个背景图片 LinearLayout...gridview.png ListView列表组件 ListView是一个用于显示列表的可以滚动的视图组,列表项也可以用适配器进行添加内容的。
三 阴影绘制,Paint画笔来绘制。我们选择在dispatchDraw()方法中绘制,为什么不用onDraw(),因为onDraw有时候在ViewGroup中不会执行。...最核心的原理就是在于,替换Window的DecorView下的LinearLayout。...#90666666")}, null, Shader.TileMode.REPEAT); //设置着色器 mPaint.setShader(mShader); //绘制时...public void onViewReleased(View releasedChild, float xvel, float yvel) { //当前回调,松开手时触发...我们在使用的时候,在布局文件中,一定要在根布局设置背景颜色,否则整个布局将会是透明的。
基于 EditText,在它的基础上增加了顶部的 Hint Text 和底部的字符计数。...回到刚才的问题:怎样才能让 LinearLayout 的绘制内容盖住子 View 呢?只要让它的绘制代码在子 View 的绘制之后再执行就好了。...例如通常一个 LinearLayout 只有背景和子 View,那么它会先绘制背景再绘制子 View;一个 ImageView 有主体,有可能会再加上一层半透明的前景作为遮罩,那么它的前景也会在主体之后进行绘制...当然,这种用法并不常见,事实上我也并没有在项目中写过这样的代码。但我想说的是,我们作为工程师,是无法预知将来会遇到怎样的需求的。...另外别忘了上面提到的那两个注意事项: 在 ViewGroup 的子类中重写除 dispatchDraw() 以外的绘制方法时,可能需要调用 setWillNotDraw(false); 在重写的方法有多个选择时
同时我们知道Activity在onResume()后才完全可见,并且初次在onResume()方法中也是拿不到View的尺寸的,这样可以推算得出:View的绘制流程是在onResume()方法执行结束后才开始的...上 wm.addView(decor, l); } } //说法二:执行makeVisible()来添加View...()方法将Activity的根View(DecorView)添加上去,进而开始绘制流程。...的MeasureSpec,接着在measureChildWithMargins()方法中又先计算出LinearLayout的MeasureSpec,再执行LinearLayout的measure()流程...的LayoutParams时match_parent时好说,LinearLayout的MeasureMode为EXACTLY,size就是父View帮其计算出的MeasureSize。