Android性能优化系列——UI优化
作为大部分的Android开发来说,很多时候都在拉界面,写业务,做优化。
在写我们的界面和业务的时候,UI的优化便会显得至关重要。因为当你的UI代码写得很垃圾的时候,就会造成卡顿,丢帧等现象(造成卡顿的原因很多,UI只是其中一中)。
Android 应用的卡顿、丢帧等,这些影响用户体验的因素绝大部分都与16ms这个值有关。Android 设备的刷新率也是 60Hz,Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染,如果超过了16ms,我们则认为发生了卡顿。
而Android端显示原理用一句话描述就是:Android应用程序调用SurfaceFlinger服务把经过测量、布局和绘制后的Surface渲染到显示屏幕上。
一、优化方向
1、布局代码
在我们的实际开发中,布局代码很多时候是通过xml和一些自定义控件来实现的。
那么在我们写布局代码XML的时候,我们可以对一些方向进行优化
- 避免过度绘制,减少布局层级;
- 有些时候,一个界面控件过多,如果只用线性布局和相对布局,会嵌套很多层级来实现绘制,这样绘制层级过高,可以用相对布局来约束各个控件的位置,减少层级。如果是简单的布局是否可以直接使用FrameLayout、LinearLayout来实现等等。
- 去掉无用的背景,资源;
- 过度绘制就是在绘制界面时,对同一个像素重复绘制了多次,但是用户能够看到的也只有最顶层绘制的内容,所以,是否可以去掉无用的背景,图片是否可以不要预设的图片资源,textview的文案是否可以先不设置。去除无用的父节点,子节点
避免View重叠;
使用?
canvas.clipRect()方法实现
只截取可见的部分,这样就能避免View重叠导致的过度绘制的问题 ,例如显示一把扑克牌的时候,因为只需要展示左边的数字就行了,所以使用此方法,不可见的部分就不会去绘制。- 使用合适的控件;
- 在项目中,可以根据项目场景使用合适的控件,例如
- ViewStub是一个可用于性能优化的控件,它是一个不可见的、零尺寸的View,可以在运行时进行延迟加载一个布局文件,从而提高显示速率。
viewstub和include比较像,都是在一个布局文件中嵌入另外一个布局文件,然而viewstub可以延迟加载,它只会在手动指定加载的时候才会加载这个布局文件,而include则会立即加载。
因此,不是必须显示的布局就可以使用ViewStub来代替,这样可以减少界面首次加载时资源消耗,提升最初加载速度。比如在无数据或者网络错误的时候,需要单独显示一个布局,那么这个布局就可以用ViewStub。、
使用merge;通过merge可以消除视图层次结构的冗余;merge标签必须使用在根布局;tips:对merge标签设置的属性是无效的。
使用一些异步加载框架;
避免View重叠实现代码;
// 老办法
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mDroids.length > 0 && mDroids.size() == mDroids.length) {
for (int i = 0; i < mDroidCards.size(); i++) {
// 每一张卡牌平移的位置
mCardLeft = i * mCardSpacing;
// 绘制整张卡牌
drawDroidCard(canvas, mDroidCards.get(i), mCardLeft, 0);
}
}
}
// 优化后
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mDroids.length > 0 && mDroids.size() == mDroids.length) {
int i;
for (int i = 0; i < mDroidCards.size() - 1; i++) {
mCardLeft = i * mCardSpacing;
canvas.save();
// 只绘制截取卡牌可见部分
canvas.clipRect(mCardLeft,
0,
mCardLeft + mCardSpacing,
mDroidCards.get(i).getHeight());
drawDroidCard(canvas, mDroidCards.get(i), mCardLeft, 0);
canvas.restore();
}
// 绘制最后一张完全可见的卡牌
drawDroidCard(canvas, mDroidCards.get(mDroidCards.size() - 1),
mCardLeft + mCardSpacing, 0);
}
}
如何查看是否过度绘制?
- 通过数据线开发者模式,使用Android端的开发者设置-调试GPU过度绘制,选择显示过度绘制区域,然后就可以看到屏幕的绘制情况了,其中我们能够看到四种颜色,分别是:蓝色、绿色、淡红色和红色。
- 使用LayoutInspector;LayoutInspector是AndroidStudio种的一个布局检查器,可以通过Tools > Layout Inspector找到,他可以检查应用中的某个界面的视图结构,但是无法查看非调式状态的应用。
- 使用Android优化工具Systrace 这个使用复杂些,但是更全面具体,具体使用看链接文章?Android优化工具Systrace - 简书
?2、自定义View代码
? ? ? ? 自定义View在开发中十分常见,当需要实现一个较为复杂的view时,就很容易漏掉很多细节。
常见问题:
- onDraw方法中过于耗时;
- onDraw方法中频繁的GC;例如我有次就很傻,会把paint和path对象的初始化放在onDraw中,这样是非常不合理的,每次绘制都会创建新的对象。可以直接定义在class类里,需要重置的时候reset一下就行了。
- 动画执行过多,选择合适的动画很重要,当一个动画过于复杂且花里胡哨的时候,叫UI做个lottie动画拿来用就好了。
- 是否在UI主线程执行了耗时操作。
- 有内存泄漏;如果代码里有静态变量,是不是该置空,动画在ondestroy调用时是不是该暂停销毁,资源是否关闭回收等等。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!