Android布局优化

布局优化措施大纲:

  • 过度绘制

Overdraw(过度绘制):描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次的UI结构里面,如果不可见的UI也在做绘制的操作,就会导致某些像素区域被绘制了多次,浪费大量的CPU以及GPU资源,因为底下被覆盖区域怎么重绘也没有意义。当view内容发生改变时,整个view都会重绘,如果层次太“丰富”,那性能就会严重下降。

过渡绘制层次:

无色: 意味着没有overdraw。像素只画了一次。
蓝色: 意味着overdraw 1倍。像素绘制了两次。大片的蓝色还是可以接受的(若整个窗口是蓝色的,可以摆脱一层)。
绿色: 意味着overdraw 2倍。像素绘制了三次。中等大小的绿色区域是可以接受的但你应该尝试优化、减少它们。
浅红: 意味着overdraw 3倍。像素绘制了四次,小范围可以接受。
暗红: 意味着overdraw 4倍。像素绘制了五次或者更多。这是错误的,要修复它们。

界面绘制层次颜色图:
  • 合理选择容器

LinearLayout易用,效率高,表达能力有限。RelativeLayout复杂,表达能力强,效率稍逊,但是relativeLayout可以减少布局层级,用一层写出复杂的嵌套。ConstraintLayout可以更好地减少层级,平铺布局层级。

Viewstub 高效占位符

我们经常会遇到这样的情况,运行时动态根据条件来决定显示哪个View或布局。常用的做法是把View都写在上面,先把它们的可见性都设为View.GONE,然后在代码中动态的更改它的可见性。这样的做法的优点是逻辑简单而且控制起来比较灵活。但是它的缺点就是,耗费资源。虽然把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,也就是说仍然会创建对象,会被实例化,会被设置属性。也就是说,会耗费内存等资源。

ViewStub是一个轻量级的View,它一个看不见的,默认不占布局位置,在Inflate布局的时候,只有ViewStub会被初始化。在要显示的时候调用 ((ViewStub)findViewById(R.id.stub_view)).setVisibility(View.VISIBLE);让其可见,ViewStub内部的布局就会被Inflate和实例化。
viewstub常用来引入那些默认不会显示,只在特殊情况下显示的布局,如进度布局、网络失败显示的刷新布局、信息出错出现的提示布局等。

Merge

当布局根布局没有实际属性仅仅起的是一个简单的父viewgroup时,可以用merge来代替,merge不会作为一个层级进行绘制。3434s

  • 业务逻辑简化

在设计业务逻辑时,尽量不要过度设计。华丽的App界面毕竟会牺牲绘制性能。在功能完成的前提下,尽量设计层级简单操作简单。

  • 优化工具

Lint工具检测布局层次

lint检测工具开启2项布局性能的检测指标,如果有布局嵌套层次深的,会检测报出问题。

点击Code菜单的Inspect Code触发Lint检测。


Layout Inspector

在Tools -> Layout Inspector,选择对应相应进程,打开界面层级检查


可根据view类型和对应id选择查看,可切换2D、3D功能进行查看。


布局加载优化

xmlPullParser IO操作,布局越复杂,IO耗时越长。
createView 反射,View越多,反射调用次数越多,耗时越长,但是这必须达到一定量级才会有明显影响。

直接解决就是不使用IO和反射技术,我们这里介绍侧面缓解,即将布局加载和解析放在子线程中,等到inflate操作完成后再将结果回调到主线程中,即使用Android为我们提供的AsyncLayoutInflater类来进行异步布局加载。

AsyncLayoutInflater

AsyncLayoutInflater是google提供的方案,让LayoutInflater.inflater过程通过子线程来做:


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    new AsyncLayoutInflater(this).inflate(R.layout.activity_main,null, new AsyncLayoutInflater.OnInflateFinishedListener(){
        @Override
        public void onInflateFinished(View view, int resid, ViewGroup parent) {
            setContentView(view);
            rv = findViewById(R.id.tv);
            rv.setLayoutManager(new V7LinearLayoutManager(MainActivity.this));
            rv.setAdapter(new RightRvAdapter(MainActivity.this));
        }
    });
 
}
布局绘制监控

获取布局文件加载耗时的方法

val start = System.currentTimeMillis()
setContentView(R.layout.activity_layout_optimize)
val inflateTime = System.currentTimeMillis() - start

这种方法很简单,因为setContentView是同步方法,如果想要计算耗时,直接将前后时间计算相减即可得到结果了

优化布局层级及复杂度

1.使用ConstraintLayout,可以实现完全扁平化的布局,减少层级
2.RelativeLayout本身尽量不要嵌套使用
3.嵌套的LinearLayout中,尽量不要使用weight,因为weight会重新测量两次
4.推荐使用merge标签,可以减少一个层级
5.使用ViewStub延迟加载

避免过度绘制

1.去掉多余背景色,减少复杂shape的使用
2.避免层级叠加
3.自定义View使用clipRect屏蔽被遮盖View绘制

参考:
https://www.jianshu.com/p/9e8f88eac490
https://mp.weixin.qq.com/s?__biz=MzA5MzI3NjE2MA==&mid=2650271556&idx=1&sn=f9c444f67322deb2a818ae2fca3f0e52#rd

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容