文章目录

  • 1.减少层级
  • 1.1页面层级查看
  • 1.2页面层级优化
    • 1.2.1合理使用RelativeLayout和LinearLayout
    • 1.2.2合理使用Merge
  • 2.提高显示速度ViewStub的使用
    • 2.1ViewStub介绍
    • 2.2ViewStub的加载方式:
    • 2.3ViewStub应用场景
    • 2.4ViewStub使用注意事项
  • 3.布局复用include
  • 4.避免过度绘制
    • 4.1过度绘制介绍
    • 4.2过去绘制的原因
    • 4.3过度绘制的检测
    • 4.4过度绘制的优化
      • 4.4.1布局文件过度绘制优化:较少页面层级,减少不必要的背景设置
      • 4.4.2自定义View优化过度绘制的优化
  • 5.子线程加载布局文件
  • 6.使用x2c对布局进行加载,

1.减少层级

1.1页面层级查看

通过使用布局view层级检测工具hierarchy viewer来查看页面的层级。这个工具在android-sdk/tools/文件夹中,默认无法连接真机,可以通过ViewServer来解决无法连接真机的问题,在需要查看的页面添加:

//就可以解决无法连接真机的问题
@Overrideprotected void onCreate(Bundle saveInstanceState) {super.onCreate(saveInstanceState);if (BuildConfig.DEBUG){ViewServer.get(this).addWindow(this);}}@Overrideprotected void onResume() {super.onResume();if (BuildConfig.DEBUG){ViewServer.get(this).setFocusedWindow(this);}}@Overrideprotected void onDestroy() {if (BuildConfig.DEBUG){ViewServer.get(this).removeWindow(this);}}

点击Evaluate Contrast可以View的颜色绿色、黄色、红色,出现黄色或者红色表示页面层级较深,需要优化。

也可以通过Lint进行代码扫描。

1.2页面层级优化

层级越少,测试和绘制的时间就越短,通常减少层级有以下两个常用方案:

1.2.1合理使用RelativeLayout和LinearLayout
  • 层级一样优先使用LinearLayout,因为RelativeLayout默认进行两次measure操作。
  • 用LinearLayout有时会使嵌套层级变多,应该使用RelativeLayout,使界面尽量扁平化。
1.2.2合理使用Merge

在Android布局的源码中,如果是Merge标签,那么直接将其中的子元素添加到Merge标签Parent中,这样就保证了不会引入额外的层级。

Merge不是所有地方都可以任意使用,有以下几点要求:

  • Merge只能用在布局XML文件的根元素。
  • 使用merge来加载一个布局时,必须指定一个ViewGroup作为其父元素,并且要设置加载的attachToRoot参数为true。
  • 不能在ViewStub中使用Merge标签。原因就是ViewStub的inf late方法中根本没有attachToRoot的设置。

但从Lint检查的配置上看,超过10层才会报警,实际上在开发时,随着产品设计的丰富和多样性,很容易超过10层,根据实际开发过程中超过15层就要重视并准备做优化, 20层就必须修改了

2.提高显示速度ViewStub的使用

2.1ViewStub介绍

ViewStub是一个轻量级的View,它是一个看不见的,并且不占布局位置,占用资源非常小的视图对象。可以为ViewStub指定一个布局,加载布局时,只有ViewStub会被初始化,然后当ViewStub被设置为可见时,或是调用了ViewStub.inflate()时,ViewStub所指向的布局会被加载和实例化,然后ViewStub的布局属性都会传给它指向的布局。这样,就可以使用ViewStub来设置是否显示某个布局。

2.2ViewStub的加载方式:

ViewStub显示有两种方式:

  • 调用:inflate()方法.
  • 直接使用ViewStub. setVisibiltity(View.Visible)方法。
2.3ViewStub应用场景

ViewStub的主要使用场景如下:

  • 在程序运行期间,某个布局在加载后,就不会有变化,除非销毁该页面再重新加载。
  • 想要控制显示与隐藏的是一个布局文件,而非某个View。
2.4ViewStub使用注意事项

使用ViewStub时需要注意以下几点:

  • ViewStub只能加载一次,之后ViewStub对象会被置为空。换句话说,某个被ViewStub指定的布局被加载后,就不能再通过ViewStub来控制它了。所以它不适用于需要按需显示隐藏的情况。

  • ViewStub只能用来加载一个布局文件,而不是某个具体的View,当然也可以把View写在某个布局文件中。如果想操作一个具体的View,还是使用visibility属性。

  • VIewStub中不能嵌套Merge标签

3.布局复用include

在开发过程中,如果一个相同的布局在很多页面(Activity或Fragment)会用到,如果给这些页面的布局文件都统一加上相同的布局代码,维护起来就很麻烦,可读性也差,一旦需要修改,很容易有漏掉的地方。

Android的布局复用可以通过标签来实现,就像提取代码公用部分一样,在编写Android布局文件时,也可以将相同的部分提取出来,在使用时,用添加进去。

4.避免过度绘制

4.1过度绘制介绍

**过度绘制(Overdraw)**是指在屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次重叠的UI结构(如带背景的TextView)中,如果不可见的UI也在做绘制的操作,就会导致某些像素区域被绘制了多次,从而浪费多余的CPU以及GPU资源。

4.2过去绘制的原因

过度绘制的主要原因:

  • XML布局->控件有重叠且都有设置背景
  • View自绘-> View.OnDraw里面同一个区域被绘制多次
4.3过度绘制的检测

可以通过手机设置中的开发者选项,打开Show GPU Overdraw选项

打开后可以根据不同的颜色观察UI上的Overdraw情况,蓝色、淡绿、淡红、深红代表4种不同程度的Overdraw情况,不同颜色的含义如下:

  • 无色:没有过度绘制,每个像素绘制了1次。
  • 蓝色:每个像素多绘制了1次。大片的蓝色还是可以接受的。如果整个窗口是蓝色的,可以尝试优化减少一次绘制。
  • 绿色:每个像素多绘制了2次。
  • 深红:每个像素多绘制了4次或者更多。严重影响性能,需要优化,避免深红色区域。

我们的目标是尽量减少红色Overdraw,看到更多的蓝色区域。

4.4过度绘制的优化
4.4.1布局文件过度绘制优化:较少页面层级,减少不必要的背景设置

使用Android自带的一些主题时,activity往往会被设置一个默认的背景,这个背景由DecorView持有。当自定义布局有一个全屏的背景时,比如设置了这个界面的全屏黑色背景,DecorView的背景此时对我们来说是无用的,但是它会产生一次Overdraw。可以通过下面的方式消除。

@Override
protected void onCreate(Bundle saveInstanceState) {super.onCreate(saveInstanceState);getWindow().setBackgroundDrawable(null);
}

针对RecyclerView Item中的Avatar ImageView的设置,在getView的代码中,判断是否获取对应的Bitmap,获取Avatar的图像之后,把ImageView的Background设置为Transparent,只有当图像没有获取到时,才设置对应的Background占位图片,这样可以避免因为给Avatar设置背景图而导致的过度渲染。

4.4.2自定义View优化过度绘制的优化

在自定义View的时候,某个区域可能会被绘制多次,造成过度绘制。

可以通过canvas.clipRect()方法指定绘制区域。

clipRect方法还可以帮助节约CPU与GPU资源,在clipRect区域之外的绘制指令都不会被执行,那些部分内容在矩形区域内的组件,仍然会得到绘制。

并且可以使用canvas.quickreject()来判断是否没和某个矩形相交,从而跳过那些非矩形区域内的绘制操作。

5.子线程加载布局文件

使用AsyncLayoutInflater在子线程加载布局文件需要添加依赖:

implementation 'androidx.asynclayoutinflater:asynclayoutinflater:1.0.0'

下面是通过子线程添加布局文件的例子:

override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)AsyncLayoutInflater(MainActivity@ this).inflate(R.layout.activity_main, null) { view, resid, parent ->setContentView(view)val contentTextView: TextView =findViewById(R.id.content);contentTextView.text = "通过子线程加载layout布局文件"}
}

6.使用x2c对布局进行加载,

setContentView加载xml布局文件,framework层主要是通过LayoutInflater.inflater方法来解析xml并创建View的,解析XML文件会涉及io读写,view的创建是通过反射来实现的,都是比较耗时的操作。

可以借助x2c来加载布局文件,可以避免反射和io读取

使用x2c加载布局文件需要导入一下依赖:

annotationProcessor 'com.zhangyue.we:x2c-apt:1.1.2'
implementation 'com.zhangyue.we:x2c-lib:1.0.6'

使用x2c加载布局文件实例:

@Xml(layouts = ["activity_main"])
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)X2C.setContentView(this, R.layout.activity_main)val contentTextView: TextView =findViewById(R.id.content);contentTextView.text = "通过X2C加载layout布局文件"}
}

x2c原理就是编译时注解:遍历注解,通过动态生成代码的方式,将反射的方式改成new的方式将View进行初始化操作。

x2c可能会存在兼容性问题,出现问题,需要做一些代码的优化。

Android-布局优化相关推荐

  1. Android布局加载慢,Android布局优化(四)X2C — 提升布局加载速度200%

    系列文章 前言 在Android布局优化(一)从布局加载原理说起中我们说到了布局加载的两大性能瓶颈,通过IO操作将XML加载到内存中并进行解析和通过反射创建View.这里介绍一种避免运行时通过IO操作 ...

  2. 深入探索Android布局优化(上)

    前言 成为一名优秀的Android开发,需要一份完备的知识体系,在这里,让我们一起成长为自己所想的那样~. Android的绘制优化其实可以分为两个部分,即布局(UI)优化和卡顿优化,而布局优化的核心 ...

  3. android listview viewstub,Android布局优化之ViewStub控件

    ViewStub是Android布局优化中一个很不错的标签/控件,直接继承自View.虽然Android开发人员基本上都听说过,但是真正用的可能不多. ViewStub可以理解成一个非常轻量级的Vie ...

  4. 一篇文章搞定《Android布局优化》

    ------<一篇文章搞定Android布局优化> 前言 为什么要进行布局优化? Android绘制原理 双缓冲机制 布局加载原理 布局加载优化的一些方法介绍 AsyncLayoutInf ...

  5. android布局优化方案,Android启动优化-布局优化

    Android启动优化-布局优化 安卓应用开发发展到今天,已经成为一个非常成熟的技术方向,从目前的情况看,安卓开发还是一个热火朝天的发展,但高级人才却相对较少,如今移动互联网的开发者也逐渐开始注重插入 ...

  6. android layout include merge,Android 布局优化之include与merge

    Android 官方提供了三个用来优化布局的标签,分别是include.merge与ViewStub,其中ViewStub是动态加载视图到内存,大家可以查阅:Android UI布局优化之ViewSt ...

  7. android 减少布局层级,Android 布局优化

    布局优化主要从以下几点进行着手 减少布局层次 和 复杂度 优化绘制流程 按需加载布局 减少布局层次 和 复杂度 首先我们可以通过以下工具分析界面布局的结构 查看布局树工具:Hierarchy View ...

  8. Android 布局优化

    在开发过程中我们经常说性能优化,但性能优化是一个比较宽泛的概念.在Android开发中性能优化可能包括:Java代码优化, 算法优化, SQLite优化, 布局优化等.那么这篇博客就来总结并分享下An ...

  9. android布局优化 工具,详解Android布局优化

    怎样才能写出优秀的Android App,是每一个程序员追求的目标.那么怎么才能写出一个优秀的App呢?相信很多初学者也会有这种迷茫.一句话来回答这个问题:细节很重要.今天我们就从最基础的XML布局来 ...

  10. Android成长日记-Android布局优化

    Android常用布局 1. LinearLayout(线性布局) 2. RelativeLayout(相对布局) 3. TableLayout(表格布局) 4. AbsoluteLayou(绝对布局 ...

最新文章

  1. 打开完成查看的CAD图纸如何一键进行打印?
  2. 2-数组中重复的数字
  3. 【Rain in ACStar HDU-3340】
  4. C语言的main函数到底怎么写的
  5. JavaFX 一 出生新手村(阅读小规则)
  6. AQS的细节--自用,非正常教程
  7. oracle trigger 延迟执行_一文详解Spring任务执行和调度
  8. 找不到该项目,请确认该项目的位置的解决办法
  9. (项目)生鲜超市(六)
  10. python问题:NameError: name 'reload' is not defined
  11. xy的联合概率密度函数怎么求_X Y的联合密度函数
  12. 国家统计局可以获取到全国5级行政区域数据
  13. wep破解——模拟chopchop攻击
  14. 无人驾驶时代的室外组网技术研究
  15. linux 查看java版本
  16. 计算机ip地址错误,网络ip地址怎么修复_ip地址错误的修复步骤-win7之家
  17. 2022团队天梯赛答案解析
  18. srec_cat 常用参数的使用
  19. QK Read, développer des habitudes de lecture
  20. 学计算机需要什么基础?

热门文章

  1. java 银联接口_银联接口测试——详细(JAVA)
  2. 华丽家族股东大会21项议案全被否
  3. 10款屏幕取色器介绍
  4. vmware + centos + MTPuTTY 配置问题解决
  5. 解决USB key在citrix虚拟桌面里使用的问题
  6. 西交大计算机英语复试,西安交大复试的详细流程
  7. 使用T卡无线升级的方法
  8. 单片机开发之数字温度计制作
  9. 【合宙air724-应用记录】FOTA远程更新
  10. Oracle数据库专家实战培训课程