Android 界面滑动卡顿分析与解决方案(入门)
导致Android界面滑动卡顿主要有两个原因:
1.UI线程(main)有耗时操作
2.视图渲染时间过长,导致卡顿
目前只讲第1点,第二点相对比较复杂待以后慢慢研究。
众所周知,界面的流畅度主要依赖FPS这个值,这个值是通过(1s/渲染1帧所花费的时间)计算所得,FPS值越大视频越流畅,所以就需要渲染1帧的时间能尽量缩短。正常流畅度的FPS值在60左右,即渲染一帧的时间不应大于17ms。
先看一个例子:
见Video1,该应用通过一组URL加载网络上的图片并显示在ListView中。从视频中可以看到滑动ListView存在一定的卡顿的现象。
分析工具1:Android systrace
打开Android开发工具中的DDMS,选中应用所在的进程并点击倒数第二个图标出现如下界面:
填上相关信息后点击OK,此时Android systrace已经开始工作,你只需要正常操作手机复现卡顿现象即可。
Android systrace 停止以后就会根据你上图中的设置生成trace.xml文件(注:此文件在火狐浏览器中无法正常浏览,需使用chrome)。
打开trace.xml后观察surfaceflinger存在很多断断续续,分布不够均匀。
放大看
在某间隔出的时间是48ms,这远远的大于17ms,正是这个原因直接导致了界面的卡顿感。
接着再看:
此处也存在不规则分布,可以看到主要的耗时操作在:
obtainView和decodeBitmap上面,看到这两个方法似乎是找到了罪魁祸首。那我们就看看这两个方法是在哪里被调用的。
通过查找源代码知道obtainView这个方法被定义在AbsListView.java这个类中,主要作用就是获得一个和数据绑定过的视图,在这个方法中调用到了
mAdapter.getView(position, transientView, this);
这个方法大家再熟悉不过了,因为在自定义Adapter的时候都要去重写getView方法,那我们可以推测卡顿的原因很有可能出自getView。毕竟这个方法里有我们自己写的很大一坨代码。
接着再看getView中最主要的方法
mCacheWrapper.getBitmapF