基础知识CPU:中央处理器,集计算、缓冲、控制等单元于一体,包括绘图功能。CPU将对象处理成多维图形、纹理(Bitmaps、Drawables等都打包成一个统一的纹理)。GPU:类似于CPU的处理器,专门用来处理Graphics。它用于帮助加快光栅化操作。当然也有相应的缓存数据(比如缓存光栅化位图等)机制。OpenGLES:它是一个面向手持嵌入式设备的3DAPI,一个跨平台、功能齐全的2D和3D图形应用程序接口API,有一套固定的渲染管线进程。OpenGLES详解DisplayList将XML布局文件转换成GPU可以识别并在Android上显示的对象来绘制。这个操作是在DisplayList的帮助下完成的。DisplayList保存着所有将交给GPU在屏幕上绘制的数据信息。光栅化是将图片等矢量资源转换成像素图像的网格,显示在屏幕上。垂直同步VSYNC:使显卡的运行与显示器的刷新率保持一致,稳定输出画质。它告诉GPU在加载新帧之前等待前一帧绘制到屏幕上。下面三张图是GPU和硬件同步的情况,RefreshRate:屏幕在一秒内刷新画面的次数,由硬件决定,比如60Hz。FrameRate:GPU绘图操作每秒的帧数,单位为30fps,正常流程图如下:渲染机制分析渲染流程介绍Android整体绘图流程如下:UIobject—>CPUprocessesmulti-维图形、纹理——通过OpeGLES接口调用GPU——>GPU光栅化图形(FrameRate)--->HardwareClock(RefreshRate)---VerticalSynchronization--->投射到屏幕Android系统发送VSYNC信号每隔16ms(1000ms/60=16.66ms),触发UI的渲染,如果每次渲染都成功,那么就可以达到流畅画面所需要的60fps。为了达到60fps,这意味着计算和渲染的大部分操作必须在16ms内完成。渲染时间轴正常情况下,AndroidGPU会在16ms内完成页面的绘制。如果一帧渲染时间超过16ms,垂直同步机制会让显示硬件等待GPU完成光栅化渲染操作,然后重新绘制界面。看起来屏幕会冻结。当GPU渲染速度过慢时,会导致如下情况,某些帧显示的图片内容会与上一帧相同。常见渲染问题GPUOverdrawOverDraw是开发中常见的优化点,指的是界面出现一层层绘制的情况。比如我们可以使用一些第三方工具来检查是否存在overdraw。比如小米魅族。每当View中的绘制内容发生变化时,都会重新执行创建DisplayList、渲染DisplayList、更新到屏幕等一系列操作。这个过程的性能取决于你View的复杂程度,View的状态变化,以及渲染管线的执行性能。当View的大小发生变化时,会重新创建DisplayList,然后进行渲染。当View被置换后,DisplayList不会被重新创建,而是会被重新渲染。因此,当界面过于复杂时,DisplayList绘制界面会延迟,造成卡顿。我们可以使用渲染工具来检测。在工具中,不同手机的渲染方式可能不同。关于激活程序Activity区域的StatusBar、NavBar、GPURendering信息。活动程序Activity区域的GPURendering信息。我们开启手机GPURendering呈现的信息。以魅族为例:说明:每条柱状线包含三部分。蓝色表示测量和绘制DisplayList的时间,红色表示OpenGL渲染DisplayList所需的时间,黄色表示CPU等待GPU处理的时间量。Android渲染优化了解Android的渲染机制对优化很有帮助,尤其是写布局的时候。降低布局层级,减少GPU渲染,对我们提高app的质量有很大的帮助。去除不必要的界面:布局层级优化使用HierarchyViewer工具查看界面层级。这个介绍可以参考我之前的博客:Android布局优化当然,Android在一些系统版本中也增加了检测overdraw的工具。比如Android中的4。DebugGPUOverdraw选项已在版本2中添加。如果您使用的是JellyBean4.3或KitKat设备,屏幕左下角会有一个计数来显示屏幕过度绘制的程度。另一种查看透支的方法是在“调试GPU透支”菜单中选择“显示透支区域”选项。选择后,应用的不同区域会覆盖不同的颜色,表示透支次数。在屏幕上对比这些不同的颜色,可以快速方便地定位透支问题。如果选择图片格式,Android界面可以使用png,最好使用png,因为32位的png颜色过渡平滑,支持透明。jpg是经过像素化和压缩的图像,其质量已降低。如果它被用作一个9path按钮和一个tile和stretch控件,那就太糟糕了,所以尽量避免它。有条件的话可以选择webpp。这种格式的图片尺寸比较小,可以满足手机显示的需要。当无法避免背景时,尽量使用Color.TRANSPARENT,因为透明色Color.TRANSPARENT不会被渲染,它是透明的。所以我们需要在设置接口的时候做一个判断:Beanbean=list.get(i);if(bean.img==0){Picasso.with(getContext()).load(android.R.color.transparent).into(holder.imageView);holder.imageView.setBackgroundColor(bean.backPic);}else{Picasso.with(getContext()).load(bean.img).into(holder.imageView);holder.imageView.setBackgroundColor(颜色。透明);}
