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

2017-06-02  本文已影响157人  6e3bd4186e4b

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

第一步 Xml布局文件解析

xml 布局文件解析流程图

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

View 绘制流程

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

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>

现在给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>

两者对比一下,明显可以看出有背景的耗时多的多,所以在平时开发中一定要慎重使用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>

现在把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>

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

工具

这里介绍常用的两种工具

结合项目谈优化方案

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

上一篇下一篇

猜你喜欢

热点阅读