美文网首页Android 移动 前端 Python Android Java
「深入理解Android布局优化 2」-常见工具的使用

「深入理解Android布局优化 2」-常见工具的使用

作者: 林栩link | 来源:发表于2019-08-25 17:14 被阅读0次

    前言

    本篇文章是《深入理解Android布局优化》系列文章的第二篇。系列的主要目的是希望将Android开发中涉及布局优化的部分做一次系统的归纳、总结和学习。本系列文章包含理论基础常见工具项目实践三个部分。

    理论基础:「深入理解Android布局优化 1」-布局的加载流程与绘制原理,主要讲解布局的加载流程与绘制原理,从源码上发现布局的性能瓶颈。

    常见工具:「深入理解Android布局优化 2」-常见工具的使用,主要讲解Android布局优化时各种常见工具的使用。

    项目实践:以一个实际的APP为例,将学习到的理论和工具,实际运用到Android开发中。

    本文中实践时使用的项目地址:https://github.com/linux-link/Fan,可以先阅读这篇文章了解这个项目一次组件化与Android Jetpack的实践

    本篇属于三个部分中的常见工具部分。

    目录

    • 工具集
    • GPU过度绘制
    • 渲染耗时
    • Layout Inspector
    • Choreographer
    • Systrace
    • Matrix
    • 总结

    正文

    一、工具集

    在Android的布局优化中也有大量的工具可供选择,这里整理了一些常用且易于上手的工具,如下所示

    工具 能力 上手难度
    GPU过度绘制 发现布局过度嵌套
    GPU呈现模式分析 统计布局绘制耗时
    Layout Inspector 列出布局树
    Choreographer 统计界面的FPS
    Systrace 统计进程的内核信息
    Matrix 全方位发现Android中的性能问题

    二、GPU过度绘制

    过度绘制(Overdraw)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次的UI结构里面, 如果不可见的UI也在做绘制的操作,这就会导致某些像素区域被绘制了多次。这就浪费大量的CPU以及GPU资源。


    过度绘制
    • 蓝色: 代表1层覆盖。像素绘制了两次。大片的蓝色还是可以接受的,若整个窗口是蓝色的,可以摆脱一层。
    • 绿色: 代表2层覆盖。像素绘制了三次。中等大小的绿色区域是可以接受的但你应该尝试优化、减少它们。
    • 淡红: 代表3层覆盖倍。像素绘制了四次,小范围可以接受。
    • 深红: 代表4层覆盖。像素绘制了五次或者更多。

    以MIUI系统为例,展示如何打开GPU过度绘制,更多设置 -> 开发者选项 -> 调试GPU过度绘制 -> 显示过度绘制区域。

    GPU过度绘制

    理论上来说深红色的区域是需要重点优化的对象,我们需要尽可能减少过度绘制,不过在实际项目中需要根据开发的具体情况来灵活判断。

    qq中存在的过度绘制现象

    三、GPU呈现模式分析

    渲染耗时顾名思义就是APP的界面在渲染过程中消耗的时间,在Android中每一桢的渲染耗时控制在16ms以内,则不会产生卡顿的感觉。

    以MIUI系统为例,展示如何查看渲染耗时。选择更多设置->开发者选项->GPU呈现模式分析->在屏幕上显示为条形图

    开启渲染耗时

    开启之后,在手机中查看任意界面,界面上都会滚动显示垂直的柱状图来表示每帧画面所需要渲染的时间,柱状图越高表示花费的渲染时间越长。如图所示

    渲染耗时条形图

    从Android 6.0之后每一桢的绘制大致有个8个步骤:


    绘制步骤
    • Swap Buffers

      表示处理任务的时间,也可以说是CPU等待GPU完成任务的时间,线条越高,表示GPU做的事情越多;

    • Command Issue

      表示执行任务的时间,这部分主要是Android进行2D渲染显示列表的时间,为了将内容绘制到屏幕上,Android需要使用Open GL ES的API接口来绘制显示列表,红色线条越高表示需要绘制的视图更多;

    • Sync & Upload

      表示的是准备当前界面上有待绘制的图片所耗费的时间,为了减少该段区域的执行时间,我们可以减少屏幕上的图片数量或者是缩小图片的大小;

    • Draw

      表示测量和绘制视图列表所需要的时间,蓝色线条越高表示每一帧需要更新很多视图,或者View的onDraw方法中做了耗时操作;

    • Measure/Layout

      表示布局的onMeasure与onLayout所花费的时间,一旦时间过长,就需要仔细检查自己的布局是不是存在严重的性能问题;

    • Animation

      表示计算执行动画所需要花费的时间,包含的动画有ObjectAnimator,ViewPropertyAnimator,Transition等等。一旦这里的执行时间过长,就需要检查是不是使用了非官方的动画工具或者是检查动画执行的过程中是不是触发了读写操作等等;

    • Input Handling

      表示系统处理输入事件所耗费的时间,粗略等于对事件处理方法所执行的时间。一旦执行时间过长,意味着在处理用户的输入事件的地方执行了复杂的操作;

    • Misc Time/Vsync Delay

      表示在主线程执行了太多的任务,导致UI渲染跟不上vSync的信号而出现掉帧的情况;

    四、Layout Inspector

    关于Layout Inspector的使用,google的官方中文文档说的非常详细,强烈推荐仔细阅读,以下内容节选自官方文档,更多更详细的内容,请仔细阅读官方文档使用 Layout Inspector 调试布局

    利用 Android Studio 中的布局检查器,可以在运行时从 Android Studio IDE 内检查自己应用的视图层次结构。 如果布局在运行时(而不是完全在 XML 中)构建并且布局没有按预期显示,这种检查将非常有用。

    按以下步骤操作,打开布局检查器:

    1. 在连接的设备或模拟器上运行您的应用

    2. 点击Tools > Android > Layout Inspector

    3. 在出现的Choose Process对话框中,选择您想要检查的应用进程,然后点击OK

      Choose Process 对话框

      默认情况下,Choose Process对话框仅会为 Android Studio 中当前打开的项目列出进程,并且该项目必须在设备上运行。 如果您想要检查设备上的其他应用,请点击Show all processes。 如果您正在使用已取得 root 权限的设备或者没有安装 Google Play 商店的模拟器,那么您会看到所有正在运行的应用。 否则,您只能看到可以调试的运行中应用。

    布局检查器会捕获快照,将它保存为.li文件并打开。 如图 2 中所示,布局检查器将显示以下内容:

    1. View Tree:视图在布局中的层次结构。
    2. Screenshot:带每个视图可视边界的设备屏幕截图。
    3. Properties Table:选定视图的布局属性。
      布局检查器

    可以在View Tree中点击视图以在屏幕截图中选择相同视图,反之亦然。 视图的所有布局属性都将显示在Properties Table中。

    如果布局包括重叠视图,则默认情况下,只有前面的视图可以在屏幕截图中点击。 要让后面的视图可以在屏幕截图中点击,请执行以下操作: 在View Tree中右键点击前面的视图,然后取消选中Show in preview。 此操作不会让视图内容消失;仅会让屏幕截图中的可点击边界消失,以便您可以点击在它后面的视图。

    如果设备上的布局发生变化,布局检查器不会更新。 必须再次点击Tools > Android > Layout Inspector,创建一个新的快照。每一个快照都将保存到project-name/captures/内一个单独的.li文件中。

    Project 窗口中的布局检查器快照(.li 文件)

    五、Choreographer

    上面介绍的几种检测方式只适合线下使用,如果我们需要在线上获取已经发布APP的卡顿情况,则适合使用Choreographer。

    通过 Choreographer.getInstance().postFrameCallback(),可以获得当前的界面的FPS,通过检查一段时间内的FPS值,我们就可以得知当前界面是否发生了卡顿。

        private static final long MONITOR_INTERVAL = 1600L; //单次计算FPS使用1600毫秒
        private static final long MONITOR_INTERVAL_NANOS = MONITOR_INTERVAL * 1000L * 1000L;//显示fps的间隔时间,1.6秒
        private static final long MAX_INTERVAL = 1000L; //设置计算fps的单位时间间隔1000ms,即fps/s;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(flipView);
            Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
                @Override
                public void doFrame(long frameTimeNanos) {
                    if (lastFrameTime == 0) {
                        lastFrameTime = frameTimeNanos;
                    }
                    long interval = frameTimeNanos - lastFrameTime;
                    if (interval > MONITOR_INTERVAL_NANOS) {
                        double fps = (((double) (frameCount * 1000L * 1000L)) / interval) * MAX_INTERVAL;
                        Log.e("fps:", fps + "");
                        frameCount = 0;
                        lastFrameTime = 0;
                    } else {
                        ++frameCount;
                    }
                    Choreographer.getInstance().postFrameCallback(this);
                }
            });
    
        }
    
    2019-06-28 22:10:18.918 24460-24460/com.link.flipview E/fps:: 61.04245124020559
    2019-06-28 22:10:19.098 24460-24460/com.link.flipview E/fps:: 61.04702584262233
    2019-06-28 22:10:19.278 24460-24460/com.link.flipview E/fps:: 61.047967231502405
    2019-06-28 22:10:19.459 24460-24460/com.link.flipview E/fps:: 61.04632000634784
    2019-06-28 22:10:19.639 24460-24460/com.link.flipview E/fps:: 61.04324641755805
    2019-06-28 22:10:19.819 24460-24460/com.link.flipview E/fps:: 61.046939755064415
    2019-06-28 22:10:19.999 24460-24460/com.link.flipview E/fps:: 61.050491907012486
    2019-06-28 22:10:20.179 24460-24460/com.link.flipview E/fps:: 61.042186309896735
    2019-06-28 22:10:20.360 24460-24460/com.link.flipview E/fps:: 61.04657118380607
    2019-06-28 22:10:20.541 24460-24460/com.link.flipview E/fps:: 61.048108852294455
    

    六、Systrace

    Systrace是Android性能优化时非常常用的工具,它可以记录短时间内的设备活动情况,并生成一份Android内核中的数据报告,例如CPU调度程序,磁盘活动和应用程序线程等等。

    Systrace生成的报告如图所示:

    Systrace HTML报告示例

    此报告提供了Android设备在给定时间段内的系统进程的总体情况。该报告还检查捕获的跟踪信息,以突出显示它所观察到的问题,例如UI jank或高功耗。

    注意:Systrace工具不会收集有关应用程序进程中代码执行的信息。有关应用程序正在执行的方法以及它使用的CPU资源的更多详细信息,请使用Android Studio中的CPU分析器。您还可以 使用CPU Profiler 生成跟踪日志并导入和检查它们。

    Systrace指南

    要了解有关Systrace工具的更多信息,请参阅以下官方指南,或者阅读这篇官方文档的译文:https://www.cnblogs.com/andy-songwei/p/10659564.html

    七、Matrix

    Matrix 是一款微信研发并日常使用的应用性能接入框架,支持iOS, macOS和Android。 Matrix 通过接入各种性能监控方案,对性能监控项的异常数据进行采集和分析,输出相应的问题分析、定位与优化建议,从而帮助开发者开发出更高质量的应用。

    Matrix-android 当前监控范围包括:应用安装包大小,帧率变化,启动耗时,卡顿,慢方法,SQLite 操作优化,文件读写,内存泄漏等等。

    • APK Checker: 针对 APK 安装包的分析检测工具,根据一系列设定好的规则,检测 APK 是否存在特定的问题,并输出较为详细的检测结果报告,用于分析排查问题以及版本追踪

    • Resource Canary: 基于 WeakReference 的特性和 Square Haha 库开发的 Activity 泄漏和 Bitmap 重复创建检测工具

    • Trace Canary: 监控界面流畅性、启动耗时、页面切换耗时、慢函数及卡顿等问题
      SQLite Lint: 按官方最佳实践自动化检测 SQLite 语句的使用质量

    • IO Canary: 检测文件 IO 问题,包括:文件 IO 监控和 Closeable Leak 监控

    关于Matrix就简单介绍到这里,更多更详细的资料以及使用帮助请查阅官方文档:
    https://github.com/Tencent/matrix#matrix_cn

    八、总结

    本篇文章梳理了6种不同的UI优化工具,这些工具中大多都比较常用,其中比较重要的有Layout Inspector和Systrace,Matrix因为需要引入第三方框架,在实际项目可以根据需要决定是否使用。下一篇将以一个《饭fan》的源码为例,通过运用这三种工具来发现、解决项目中性能问题。

    相关文章

      网友评论

        本文标题:「深入理解Android布局优化 2」-常见工具的使用

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