[半分钟读完]Android性能实例研究续
这是《几分钟读完》的第二篇,本文是 Android 大神 Romian Guy 的文章 Android Performance Case Study Follow-up。看完这篇,强烈推荐去看大神的原文,引用大神的一句话:
Don’t make assumptions, measure!
别瞎蒙,要检测!
大神在没有任何源代码情况下,来分析 Falcon Pro 性能问题。文中 Romain 使用 Android 开发工具 Tracer for OpenGL(这里有这个工具的详细使用方法)。这个工具用来收集所有的 UI 控件发送给 GPU 的绘图命令,所以用它可以清楚的看出 GPU 是怎样逐步绘制你的 View 的。
因为他是大神,从 Trace 中很快就发现了有大量的 SaveLayer/ComposeLayer 命令来创建临时的硬件图层,这是因为 View 直接或者间接调用了 Canvas.saveLayer()
,大神很快就想到了,这是因为 View 中不合理使用了 setAlpha()
导致的。最后定位到一个第三方的 ViewPager 页面指示器库是罪魁祸首。
结论:UI 框架在绘制 alpha<1
的 View,并且满足下面的条件的时候,会使用 Canvas.saveLayer()
来创建临时的硬件图层:
getAlpha()
返回值 < 1onSetAlpha()
返回false
getLayerType()
返回LAYER_TYPE_NONE
hasOverlappingRendering()
返回true
GPU 为了绘制这个临时图层,需要把绘制命令发送到不同的绘制目标,这样操作正好是 GPU 非常不擅长的。其实这也比较好理解,因为是有透明度 View,需要同时把 View 下面的图层和本图层综合出最后的结果。解决的方法就是打破这些条件。