美文网首页
从View的工作原理介绍Android view的性能优化

从View的工作原理介绍Android view的性能优化

作者: 6e3bd4186e4b | 来源:发表于2017-06-02 16:06 被阅读157次

在开发过程中,经常会接触到“性能优化”这个问题,比如内存优化、网络优化、视图优化。为了解决优化内存和网络问题,通常的做法都是采用第三方库(比如OkHttp、Glide、Fresco);而关于视图优化,则需要开发者拥有一个好的视图优化的常识。对于我们开发者来说,了解一些View性能优化的常识,增强开发技巧,也是一门必备功课。</br>
  在文章开始前,先提个问题,Android中的xml布局怎么显示到屏幕上的?这个问题涉及很广,从软件到硬件,整个流程我就不花篇幅去讲解,这里有个视频应该能很好的回答这个问题,视频网址:https://www.youtube.com/watch?v=WH9AFhgwmDw
  看完上面的视频之后,我们就一些和开发过程中密切相关的细节做具体分析流程

第一步 Xml布局文件解析

xml 布局文件解析流程图

<b>其中一些优化的标签:<b>

  • ViewStub 标签

      ViewStub就是一个宽高都为0的一个View,它默认是不可见的。只有通过调用 setVisibility() 函数或者 Inflate() 函数才会将其要装载的目标布局给加载出来,从而达到延迟加载的效果。在ViewStub布局可显示之前,系统不会消耗资源去实例化里面的布局,可以节省系统资源消耗。<p>
  • include 标签

      按照官方的意思,include就是为了解决重复定义相同布局的问题。相当于Java代码中将相同的部分抽取出来,然后复用,需要的时候引入它即可,而不必每次都自己写一遍。<p>
  • merge 标签

      merge它可以删减多余的层级,优化UI。例如你的主布局文件是垂直的LinearLayout,这时使用include将目标布局引入进来,新布局也是垂直的LinearLayout,那么这个新的LinearLayout就没有任何意义了。使用的话反而增加计算和绘制时间,这时就可以使用<merge/>标签优化。merge原理就是在解析xml时候,如果是 <merge/> 标签,那么直接将其中的子元素添加到merge 标签parent中,这样就保证了不会引入额外的层级。

View 绘制流程

我们都知道,View 的绘制大致分为三个阶段:测量、布局和绘制,这三个阶段各自的作用如下:

  • measure: 计算大小
  • layout:计算位置
  • draw:将视图显示在屏幕上

    大致流程如下:

    View 绘制流程

    如果是一个view树,那么measure、layout、draw都应该是一个递归操作,具体流程如:
  • View树measure流程图

    measure递归操作
  • View树layout流程图

    layout递归操作
  • View树draw流程图

    draw流程图

View渲染过程

这里推荐一篇博客http://hukai.me/android-performance-render ,本篇文章就不多讲了。

常识

1、减少View层级。这样会加快Inflate解析xml和View的循环遍历过程。

2、去除不必要的背景。由于在draw的步骤中,会单独绘制背景。因此去除不必要的背景会加快View的绘制。

3、尽可能少的使用margin、padding。在测量和布局的过程中,对有margin和padding的View会进行单独的处理步骤,这样会花费时间。我们可以在父View中设置margin和padding,从而避免在子View中每个单独设置和配置。

4、去除不必要的scrollbar。这样能减少draw的流程。

5、慎用渐变,能减少draw的流程。

6、View的过渡绘制。

7、View的频繁重新渲染。

8、UI线程中进行耗时操作。

9、冗余资源及错误逻辑导致加载和执行缓慢。简单的说,就是代码写的烂。

10、频繁触发GC,导致渲染受阻。当系统在短时间内有大量对象销毁,会造成内存抖动,频繁触发GC线程,而GC线程的优先级高于UI线程,因而会造成渲染受阻。

量化

上一章节介绍的常识都是一些理论知识,相比之下量化后的数据更有说服力,下面就介绍两个量化的例子:

1、有背景和没有背景能优化多少?

没有背景的布局

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <FrameLayout
        android:id="@+id/view_content"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        >
        <TextView
            android:id="@+id/tv_test"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="测试hierarchyView"
            />
        </FrameLayout>
</FrameLayout>
  • 没有背景耗时(数据来自Hierarchy View,具体耗时和设备有关):
    • Measure:0.025ms
    • Layout: 0.013ms
    • Draw:0.322ms

现在给view_content增加一个白色的背景

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <FrameLayout
        android:id="@+id/view_content"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:background = "#ffffff"
        >
        <TextView
            android:id="@+id/tv_test"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="测试hierarchyView"
            />
        </FrameLayout>
</FrameLayout>
  • 白色背景耗时
    • Measure:0.025ms
    • Layout:0.013ms
    • Draw:2.425ms

两者对比一下,明显可以看出有背景的耗时多的多,所以在平时开发中一定要慎重使用view background这个属性,它造成的耗时可是个大头。

2、加一层布局会增加多少耗时?

先贴上测试代码

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <FrameLayout
        android:id="@+id/view_content"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:background = "#ffffff"
        >
        <TextView
            android:id="@+id/tv_test"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="测试hierarchyView"
            />
        </FrameLayout>
</FrameLayout>
  • 耗时
    • Measure:0.025ms
    • Layout:0.013ms
    • Draw:2.425ms

现在把tv_test移到外面来

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <FrameLayout
        android:id="@+id/view_content"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:background = "#ffffff"
        >
    </FrameLayout>
    <TextView
            android:id="@+id/tv_test"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="测试hierarchyView"
            />
</FrameLayout>
  • 耗时
    • Measure:0.028ms
    • Layout:0.016ms
    • Draw:2.288ms

两者总耗时比较可以看出扁平化的布局耗时稍微少一点(布局嵌套如果深一点差值会更明显,有兴趣可以试一下),这里也可看出在View的绘制过程中,draw的时间最长。

工具

这里介绍常用的两种工具

结合项目谈优化方案

目前我们项目Activity数量已经达到252个,也就是说我们的app有252个界面,其中有许多界面都可以做优化,尤其是对一些布局比较复杂,视图比较多的页面可以针对性的做优化,可以从以下几个点进行
1、检查布局的background属性,看看有没有重叠现象
2、尽量降低布局嵌套层次
3、合理使用include、merge、ViewStub等标签
4、删除冗余的资源

相关文章

  • 从View的工作原理介绍Android view的性能优化

    在开发过程中,经常会接触到“性能优化”这个问题,比如内存优化、网络优化、视图优化。为了解决优化内存和网络问题,通常...

  • Android面试题汇总

    我的简历相关的 Android应用性能的优化 性能优化1 Android自定义view Android自定义Vie...

  • 复习

    RecyclerView的缓存机制bitmap 优化性能优化view 的绘制流程浅析LRUCache原理(Andr...

  • 无标题文章

    APP性能优化 UI卡顿优化 View的绘制原理 UI卡顿原理分析 UI卡顿检测分析 BlockCanary原理分...

  • 一步一步走进 自定义View

    View简介 1.View原理及其子类介绍 View是Android UI组件的基类,ViewGroup是容纳UI...

  • Android - View 的工作原理

    Android-View 的工作原理 View 的工作流程主要指的是 measure、layout、draw 这三...

  • android布局绘制的过程

    android View 绘制工作原理 从Activity开始的setContentView开始 源码里面是: p...

  • View 的工作原理

    目的 介绍 View 的工作原理,为了更好地自定义 View(这才是学习的重点),需要掌握 View 的底层工作原...

  • Android 高级开发:基础知识整理 <二>

    6,Android View知识点 Android本身的View体系非常庞大的,如果要完全弄懂View的原理是很困...

  • Android性能优化工具收集

    一些比较好的android性能优化教程、视频以及工具的收集 View Infamous ViewHolder Pa...

网友评论

      本文标题:从View的工作原理介绍Android view的性能优化

      本文链接:https://www.haomeiwen.com/subject/ubsufxtx.html