Open a284628487 opened 6 years ago
Android 包含一些设备上开发者选项,可直观地了解您的应用在何处出现界面渲染问题,比如执行太多不必要的渲染工作,或执行长时间的线程和GPU操作。
Profile GPU Rendering工具以滚动直方图的形式直观地显示渲染界面窗口帧所花费的时间(以每帧16毫秒的速度作为对比基准)。
在性能较低的 GPU 上,可用的填充率(GPU 填充帧缓冲区的速度)可能很低。 随着绘制帧所需的像素数增加,GPU 可能需要花较长时间来处理新命令,并要求系统的其余任务等待,直到系统可以跟上需求。 此分析工具可帮助您确定 GPU 何时因尝试绘制像素而负担过重,或何时因大量的过度绘制而被拖累。
开发者选项:Monitoring -> Profile GUP Rendering
,选择On screen as bars
在设备屏幕上叠加图表显示。
图表内容:
Android 6.0及更高版本上,每个竖条区块多达8条,从上到下分别是:
表示 CPU 等待 GPU 完成其工作的时间。 如果此竖条升高,则表示应用在 GPU 上执行太多工作。
表示 Android 的 2D 渲染器向 OpenGL 发起绘制和重新绘制显示列表的命令所花的时间。此竖条的高度与它执行每个显示列表所花的时间的总和成正比—显示列表越多,红色条就越高。
表示将位图信息上传到 GPU 所花的时间。大区段表示应用花费大量的时间加载大量图形。
表示用于创建和更新视图显示列表的时间。此条段代代表绘制工作,也即对应于 onDraw 方法。
表示在视图层次结构中的 onLayout 和 onMeasure 回调上所花的时间。 大区段表示此视图层次结构正在花很长时间进行处理。
表示评估运行该帧的所有动画程序所花的时间。如果此区段很大,则表示您的应用可能在使用性能欠佳的自定义动画程序,或因更新属性而导致一些意料之外的工作。
表示应用执行输入 Event 回调中的代码所花的时间。如果此区段很大,则表示此应用花太多时间处理用户输入。考虑将此处理任务分流到另一个线程。
表示应用执行两个连续帧之间的操作所花的时间。它可能表示界面线程中进行的处理太多,而这些处理任务本可以分流到其他线程。
Android 6.0以下
当在同一帧中相同像素被多次绘制时,便会发生过度绘制。因此此图可显示您的应用可能在何处执行太多不必要的渲染工作,这可能是 GPU 多此一举地渲染用户不可见的像素所导致的性能问题。
开发者选项:Hardware accelearated rendering -> Debug GUP Overdraw
中选择Show overdraw areas
。
界面颜色表示的含义:
带透明度的绘制,和标准绘制(系统将隐藏已经绘制好的像素点,直接在该像素点上面绘制另一个不透明的像素)不同, 带透明度的物体的绘制,需要先把已经存在的像素绘制出来,然后再绘制透明度,实现混合效果。 Link
Sync/upload表示Bitmap从CPU内存空间上传到GPU内存空间所花费的时间。CPU和GPU使用的是不同的内存区域,所以图片需要进行传递。 绘制一个图片的流程:在GUP绘制一个图片之前,系统需要先将图片信息传递到GPU内存区,然后GPU会将图片缓存起来, 避免再次绘制的时候需要再次传递图片数据造成时间消耗,之后才能渲染绘制到屏幕当中。
由于每一帧画面的所有的资源都需要在GPU内存区域当中,所以如果有大量的小的资源,或者少量的大的资源的情况下,都会导致上传时间过长, 比如app显示了一张和屏幕差不多大小的图片,或者app显示了大量的小图片。
两种提升措施:
prepareToDraw()
方法,异步预先上传图片资源。图片必须上传到GPU内存之后才能进行绘制,通常这是在图片第一次被绘制的时候才进行的操作,但是上传操作有一定的耗时。
Android N
之后才有的api,该方法将在RenderThread中启动一个异常上传任务将图片上传到GPU内存,如果图片已经上传过,则不做处理。
提前调用这个方法,可以节约一定的时间,推荐这样使用:在worker线程中将图片解码完成之后,直接调用该方法(也是在worker线程)。
[Link](https://developer.android.com/reference/android/graphics/Bitmap#prepareToDraw())
尽管此工具名为 Profile GPU Rendering,但所有受监控的进程实际上发生在 CPU 中。通过将命令提交到 GPU 触发渲染,GPU 异步渲染屏幕。 在某些情况下,GPU 会有太多工作要处理,在它可以接收新命令前,CPU 必须进入等待状态。 在等待时,您将看到橙色条和红色条中出现峰值,且命令提交将被阻止,直到 GPU 命令队列腾出更多空间。
Analyze -> Inspect Code
可以分析出布局文件中可以优化的地方。尽量减少冗余View层级。
Lint
工具可以帮助标记此问题,从而减少调试时间。
使用 <merge>
标签或者 <include>
标签。
选择合适的 layout 布局,比如使用 ConstraintLayout 替换 RelativeLayout。
https://developer.android.com/studio/profile/inspect-gpu-rendering