您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
Android应用性能优化之优化列表头像过度绘制
 
作者:zH_GioN 来源:博客园 发布于: 2015-6-1
   次浏览      
 

操作的是否顺畅、卡顿,决定着整体的流畅程度。

事实上android跟iphone的差别,个人觉得很大程度上决定于流畅程度,无论是动画,还是列表滑动等相关操作,流畅与否,对于用户而言,虽然他们说不出来哪里不对,但是卡与不卡的反馈却是很直接的。

Google也设法想改变这局面。在4.0之后的应用(最低版本4.0)默认开启硬件加速,并且4.1新加了一个Project Butter(黄油计划),设法将渲染帧速提升到60fps。

虽然能看到android的进步,但在实际中,并没有特别的变化,原因很简单。一方面android在3.0之后才开始支持GPU渲染。另外一方面,也是想做此系列的重要原因,应用的顺畅不能仅靠系统去努力,开发者在代码中给予力量才是最重要的。

坐看市面上应用,抛开需求,仅在操作流程程度上,国外应用至少甩开国内应用N条街,从最基本的硬件加速开启,到整体控件优化方案,这就是为什么很多4.1以上的手机,在使用应用上依然找不到那种属于顺畅的感受。

先申明,菜鸟一枚,很多东西都只是初步猜想,能力有限,短时间内无法深入确认原理,并且有些东西是反编其他应用看来的,可能达到了效果,但一些关键的类似适配之类的代码没看到。所以有错在所难免的嘛,希望体谅。

Android应用性能优化之优化列表头像过度绘制

下图为自己的应用蜂巢的主题时间轴列表:

因为在开启了硬件加速后,还是没有达到60帧数的要求,存在卡顿的感觉。所以我们一步步来改善他吧

这次我们先解决一个很普遍的问题,那就是过度绘制。

而且过度绘制,其实很好理解,举个例子,一个白色背景的窗口,上面有一个黑色背景的布局,最后上面显示的是一个按钮。事实上最后显示的时候,按钮下面的白色背景和黑色背景是看不到的,但在绘制的时候确都画上去了。

当然过度绘制是无法完全避免的,适度的是可以接受的,但过多了之后就会造成性能影响。引用大牛的分析就是:

备的内存带宽是有限的,当过度绘制导致应用需要更多的带宽(超过了可用带宽)的时候性能就会降低。带宽的限制每个设备都可能是不一样的。一个好的参考目标就是控制过度绘制为2X;这说明您可以绘制一次屏幕,然后在上面绘制最多2次内容,一共绘制每个像素3次。

android提供了对应的工具进行检测,在4.2的开发者选项中,提供了一个叫做“显示GPU过度绘制”的选项。当然,所要分析的页面必须要开启硬件加速。

通过颜色来区别标示过度绘制的情况:蓝色1x过度绘制、绿色2x过度绘制、淡红色3x过度绘制和红色超过4x过度绘制。

我们先用这个来看下:

头像跟显示的主体图片都是淡红色,并且区域占的很大,所以我们先依次把这两个图片过度绘制的问题解决了。

知道了要优化的地方,我们就要分析具体问题了,其实优化过度绘制的通用思路比较简单,就是要知道具体每一层都绘制了什么,删去完全没必要的层级。当然这是最基本的思路,要实现这个思路我们就需要用到另外一个工具Tracer for OpenGL。

这个工具能够记录每一次绘画的动作,并且能展现出来,这样我们就能看到具体的绘画情况了。

使用要求:

工具需要连接到一个运行Android 4.1(API级别16)或更高设备上的运行,所以记得开启4.1及以上模拟器或真机来进行分析调试

使用方法:

打开ADT的Tracer for OpenGL Es标签(默认好像是没添加的,需要手动添加下),有一个向上的箭头。点击后会弹出选项对话框,如下。

Device:选择需要调试的设备。

Application Package:填入包名,也就是AndroidMainfest.xml里面谢的那个,比如com.example.XXXX

Activity to launch:填入需要测试的页面路径。也就是除了包名外的身下部分。比如test.xxxActivity

Data Collection Options:有三个选项,第一个选项是快速定位对应帧,具体的效果就是能看到每一帧最终生成的样子,第二个选项是关键,查看每帧的每个绘制命令及效果。

Destination File:存放数据的路径,建议找个剩余空间大的地方。

都选择完后,点击Trace后就开始分析。设备会直接进入所填写的分析界面,如果没有进入,或者进入后工具的状态没有任何改变,就说明失败了,需要重新设置并重来。当设备上显示完整你需要分析的界面部分时,稍过一会,就可以点击stop来查看结果了。

[个人经验:第三方工具就没有一个不奇葩的,此工具也不例外。依照之前经验,建议点击之前,对应的设备记得把锁屏界面解开,否者失败的可能性很大]

在结果中可以看到每个发送给gpu的GL命令,选择每一帧,能在Frame Summary中看到每一帧的最终效果。并且能在Detail界面中看到每一个绘画命令执行后的界面状态。

以下为头像区域的绘制情况:

能看出,其实是先将头像的图片画了出来,然后再将一个4个圆角的图片画在之前图片的上面。形成圆角头像的效果。

以上讲的只是一个整体的思路,通过对应的工具,查找出每一步的绘画步骤,来规避多余的绘制命令,从而达到减少过度绘制的目的。

接下来开始解决这个头像的问题,按常理将要实现这个效果,就必须要图片覆盖,所以用通用的思路是无法解决这个过度绘制的问题。当初这个制作圆角头像的方法是从path那里学来的,那我们就看看,path是不是也无法解决此问题。

好吧,蓝色,证明path能解决这个过度绘制。

看下反编出来的代码,应该能猜个大概出来。

首先先看看布局,是不是普通的ImageView.

path首页里的布局东西真心多,终于在茫茫大海中找到了我们的目标。

果真,重写了,不是普通的控件,CacheableProfilePhoto。Google了一下,看来不是开源的空间,那就直接从代码里猜吧。

此控件继承于OverlayImageView,那我们先看看OverlayImageView是啥

恩恩,看来就是他了,作为一个继承于ImageView的家伙,果断直接看OnDraw方法。[常人是无法忍受path这满地都是食物名称为变量的反编代码.坑爹啊]

发现绘制的整体流程是①先获取一个DrawingCanvas类型的变量,如果此变量为空,则初始化它。②然后似乎有一个方法,将此变量作为参数传入了进去。③之后此变量可以返回一个bitmap,④最后将这个bitmap画在canvas上。

流程挺简单,简直的关键就在于,画上去的bitmap到底是个啥东西。

要弄懂这个东西,我们就必须弄懂DrawingCanvas是什么。

看来是一个Canvas,并且拥有一个类型为Bitmap的变量,有一个方法来返回这个bitmap变量。

在DrawingCanvas的代码里,似乎看不到绘制的处理,说明另有其他地方,之前在OverlayImageView看到个方法将此类型的变量作为参数,那我们就看看那个方法做了什么事情。

在OverlayImageView中有个叫做protected void wheatbiscuit(DrawingCanvas paramDrawingCanvas)的方法

代码片段一

代码片段二

这下有点清晰了,此方法中对传入的DrawingCanvas变量绘制了两次。那现在我们方便来看下这两次方便都画了什么。

这是第一次,那很明显,应该是属于这个ImageView的图片资源

Drawable localDrawable1 = getDrawable();

这是第二次,redwine是在setOverlayResource方法中被赋值的,此方法传入的是i = localTypedArray.getResourceId(0, -1);最后定为到的是app:overlay="@drawable/moment_avatar" ,那就明白了,第二次绘制上去的,其实就是覆盖在上面的画有4个圆角的图片。

Bitmap localBitmap2 = ((BitmapDrawable)this.redwine).getBitmap();

终于真相大白了,总结下,其实path就是将原本每次都要绘制两次的图片,事先就绘制好并且缓存起来,这样就不会过度绘制了。

来,我们看看效果:

看吧,头像变蓝了吧?!成功。

当然,还有很多代码细节这里就不详细展开说了,毕竟同样的思想,可以有不同的代码实现逻辑。

最主要还是想传达一个思路。

或许这思路,大家都懂,就我刚知道吧。o(╯□╰)o

这次关于头像的优化就先写到这吧,废话多了点,请见谅。

不过奇怪的是,正文图片的过度绘制,从分析来看似乎正常了耶=。=,忘记之前改了哪了...假动作晃到自己了。明天认真翻代码下。

   
次浏览       
 
相关文章

手机软件测试用例设计实践
手机客户端UI测试分析
iPhone消息推送机制实现与探讨
Android手机开发(一)
 
相关文档

Android_UI官方设计教程
手机开发平台介绍
android拍照及上传功能
Android讲义智能手机开发
相关课程

Android高级移动应用程序
Android系统开发
Android应用开发
手机软件测试
最新活动计划
软件架构设计方法、案例与实践 8-23[特惠]
Linux内核编程及设备驱动 8-15[北京]
Python、数据分析与机器学习 8-23[特惠]
嵌入式软件架构设计 8-22[线上]
QT应用开发 9-5[北京]

android人机界面指南
Android手机开发(一)
Android手机开发(二)
Android手机开发(三)
Android手机开发(四)
iPhone消息推送机制实现探讨
手机软件测试用例设计实践
手机客户端UI测试分析
手机软件自动化测试研究报告
更多...   

Android高级移动应用程序
Android应用开发
Android系统开发
手机软件测试
嵌入式软件测试
Android软、硬、云整合

领先IT公司 android开发平台最佳实践
北京 Android开发技术进阶
某新能源领域企业 Android开发技术
某航天公司 Android、IOS应用软件开发
阿尔卡特 Linux内核驱动
艾默生 嵌入式软件架构设计
西门子 嵌入式架构设计
更多...