Android绘制优化与内存优化

本文深入探讨了Android应用的绘制优化和内存优化。从绘制原理出发,分析了导致卡顿的原因,介绍了使用GPU渲染模式分析工具、系统跟踪Systrace和CPU分析器来检测和解决问题。在内存优化部分,讲解了如何避免内存泄漏,使用内存性能分析器进行检查,并提供了布局优化的多种方法。最后,文章提供了具体的实例和工具使用指南,帮助开发者提升应用的性能和用户体验。
摘要由CSDN通过智能技术生成

一、绘制优化

1.绘制原理

说到绘制优化,首先不得不提的就是绘制原理。我们知道,View的绘制流程有3个步骤,分别是measure、layout和draw,它们主要是运行在系统的应用框架层,而在底层则是由CPU来进行Measure、Layout、Record、Execute的数据计算工作,由GPU来进行栅格化、渲染。CPU和GPU通过共同操作图形驱动层维护的一个队列来完成绘制,即CPU将display list添加到该队列中,GPU从队列中取出数据进行绘制。
再来说说帧数,我们知道,画面在60fps时候不会感受到卡顿,如果低于60fps则会感受到卡顿,因此若要保持流畅,则屏幕需要在1秒内刷新60次,也就是说,需要将View绘制时长控制在16ms以内。
Android系统每隔16ms发出一种定时中断信号来触发对UI进行渲染。如果每次渲染都成功,就能够达到流畅画面的60fps,但是如果某个操作需要花费更多时间,那么在得到信号时就无法进行征程的渲染,这样就会发生丢帧现象。

2.卡顿原因

产生卡顿的原因主要有以下几点:
①布局Layout过于复杂,无法在16ms内完成渲染;
②同一时间动画执行的次数过多,导致CPU或GPU负载过重;
③View过度绘制,导致某些像素在同一时间内被绘制多次;
④在UI线程中做了稍微耗时的操作;
⑤GC回收时暂停时间过长或者频繁的GC产生大量的暂停时间。

3.使用GPU渲染模式分析工具进行分析

在Android4.1以上的设备中,以魅族Flyme8.1.5.0A为例(底层为Android9),在开发者选项中找到“监控”,将GPU渲染模式分析设为“在屏幕上显示为条形图”,这时候就会在屏幕出现彩色的柱状图,如下图所示:
在这里插入图片描述
对于每个可见应用,都将会显示一个图形。图中沿水平轴的每个竖条代表一个帧,每个竖条的高度表示渲染该帧所花的时间(以毫秒为单位),水平绿线表示 16 毫秒。要实现每秒 60 帧,代表每个帧的竖条需要保持在此线以下,当竖条超出此线时,可能会使动画出现暂停。
下表介绍了使用运行 Android 6.0 及更高版本的设备时分析器输出中某个竖条的每个区段(来源:Android开发者官网)。
在这里插入图片描述
4.0(API 级别 14)和 5.0(API 级别 21)之间的 Android 版本具有蓝色、紫色、红色和橙色区段。低于 4.0 的 Android 版本只有蓝色、红色和橙色区段。下表显示的是 Android 4.0 和 5.0 中的竖条区段。
在这里插入图片描述
共同都有的是橙色、红色以及蓝色。

  • 橙色:代表处理的时间,是CPU告诉GPU渲染一帧的地方,是一个阻塞调用,因为CPU会一直等待GPU发出接到命令的回复,所以如果橙色柱状图很高,则表明GPU很繁忙
  • 红色:代表执行的时间,是Android进行2D渲染Display List的时间。如果红色柱状图很高,可能由于重新提交了视图而导致的,另外,复杂的自定义View也会导致红色的柱状图变高;
  • 蓝色:代表测量绘制的时间,也就是需要多长时间去创建和更新Display List。如果蓝色柱状图很高,可能有许多自定义视图绘制,或者View的onDraw方法执行的工作很多

4.使用系统跟踪Systrace工具进行分析

“系统跟踪”就是记录短时间内的设备活动。系统跟踪会生成跟踪文件,该文件可用于生成系统报告,对于UI显示性能,比如动画播放不流畅、渲染卡顿等问题提供了分析数据。
“系统跟踪”应用是一款用于将设备活动保存到跟踪文件的 Android 工具。在搭载 Android 10(API 级别 29)或更高版本的设备上,跟踪文件会以 Perfetto 格式保存;在搭载较低版本 Android 系统的设备上,跟踪文件会以 Systrace 格式保存。
Systrace 是平台提供的旧版命令行工具,可记录短时间内的设备活动,并保存在压缩的文本文件中。该工具会生成一份报告,其中汇总了 Android 内核中的数据,例如 CPU 调度程序、磁盘活动和应用线程。systace对检测应用UI表现非常有效,因为它可以分析代码和帧率来识别出问题区域,然后提出可能的解决方案
Perfetto 是 Android 10 中引入的全新平台级跟踪工具。这是适用于 Android、Linux 和 Chrome 的更加通用和复杂的开源跟踪项目。与 Systrace 不同,它提供数据源超集,可以以 protobuf 编码的二进制流形式记录任意长度的跟踪记录。
Perfetto 和 Systrace 可交互使用。
由于目前使用Android 10以下的手机还很多,这里就以Systrace为例进行说明。操作步骤如下:
①从Android Studio下载并安装最新的Android SDK工具(可依次点击 Tools > SDK Manager进入 SDK Manager进行查看)。
②安装Python(https://www.python.org/)(由于脚本仅支持2.X版本,请下载2.7版本)并将其添加到工作站的PATH环境变量中,如下图所示:
在这里插入图片描述
然后安装pywin32模块,可以使用pip命令进行安装。
在这里插入图片描述
③将android-sdk/platform-tools/添加到PATH环境变量。此目录包含由systrace程序调用的Android调试桥二进制文件 (adb)(systrace 命令在 Android SDK 工具软件包中提供,并且可以在 android-sdk/platform-tools/systrace/ 中找到)。
④使用 USB 调试连接将搭载Android 4.3(API 级别 18)或更高版本的设备连接到开发系统。
⑤使用以下语法通过命令行运行 systrace来为应用生成 HTML 报告:

 python systrace.py [options] [categories]

例如,以下命令会调用systrace来记录设备活动,并生成一个名为mynewtrace.html的HTML报告。

python systrace.py -o mynewtrace.html sched freq idle am wm gfx view \
        binder_driver hal dalvik camera input res

可以运行以下命令来查看已连接设备支持的类别列表:

python systrace.py --list-categories

如果未指定任何类别或选项,systrace会生成包含所有可用类别的报告,并使用默认设置。
在这里插入图片描述
⑥使用Chrome打开mynewtrace.html文件进行分析。报告界面如下图所示:
在这里插入图片描述
我们可以使用W键和S键进行放大和缩小;使用A键和D键进行左右移动。
接下来我们来具体讲解下这个报告怎么看。
整体观察,可以看见页面被分为了四部分,从上到下分别是用户互动、CPU 活动、应用区域以及Alert区域。接下来就分别说下这四个部分。

  • 用户互动:这一部分包含表示应用或游戏中的具体用户互动(例如点按设备屏幕)的条形图。这些互动可用作有用的时间标记。
    在这里插入图片描述
  • Alert区域:可以看到互动区上面有很多A圆圈,这些A圆圈表示性能有问题的点,单击任意问题点,都可以在Alert区域看到相关的问题描述,如下图所示:
    在这里插入图片描述
    这个Alert指出了View在Measure/Layout 时耗费了大量的时间,导致出现jank(同一帧绘制了多次)。给出的建议是避免在动画播放期间控制布局。
    也可以单击最右边的Alerts按钮查看Alert的总体分析,如图所示:
    在这里插入图片描述
    单击任意Alert type项,用户互动区域会直观显示有问题的点。
    在这里插入图片描述
    Alert区域也会显示对应Alert type项的总体信息。
    在这里插入图片描述
  • CPU 活动:这一部分中,每一行代表一个CPU核心和它执行任务的时间片,放大后会看到每个色块代表一个执行的进程,色块的长度代表这个进程执行的时间,如下图所示:
    在这里插入图片描述
    单击CUP6中的RenderThread线程色块,会给出RenderThread线程的相关信息。
    在这里插入图片描述
    可以看到,上图给出了当前色块所运行的线程和进程、开启时间和持续时间等信息。
  • 应用区域:这个区域会显示各个进程的帧数,如下图所示:
    在这里插入图片描述
    我们以其中的com.tencent.mm为例来进行具体说明,com.tencent.mm如下图所示:
    在这里插入图片描述
    Systrace 会给出应用中的Frames分析,每一帧就是一个F圆圈,F圆圈有三种颜色,其含义如下:
    绿色:16.6 毫秒内渲染完毕;
    黄色或红色:渲染时间超过16.6 毫秒。其中红色的更严重一些。
    单击红色F圆圈,会给出该Frame的信息,如下图所示:
    在这里插入图片描述
    可以看到这一帧出现了三个问题,分别是Inflation during ListView recycling、Expensive measure/layout pass和long View#draw(),单击箭头可以查看详细信息。

下面是systrace对每一种警告类型的解释:
Scheduling delay:渲染一帧的工作被推迟了几个毫秒,从而导致了不合格。确保UI线程上的代码不会被其他线程上完成的工作阻塞,并且后台线程(例如,网络或位图加载)在android.os.Process#THREAD_PRIORITY_BACKGROUND中运行或更低,因此它们不太可能中断UI线程。
Expensive measure/layout pass:测量/布局花费了很长时间,导致掉帧,要避免在动画过程中触发重新布局。
Long View#draw():记录无效的绘图命令花费了很长时间,在View或Drawable自定义视图时,要避免做耗时操作,尤其是Bitmap的分配和绘制。
Expensive Bitmap uploads:修改或新创建Bitmap视图要传送给GPU,如果像素总数很大,这个操作会很耗时。因此在每一帧中要尽量减少Bitmap变更的次数。
Inefficient View alpha usage:将alpha设置为半透明值(0<alpha<1)会很耗性能,尤其是对大视图。所以最好短暂地使用alpha属性。
由于systrace是以系统的角度返回一些信息的,因此只能为我们提供一个概览,它的深度是有限的。我们可以用它来进行粗略的检查,以便了解大概的情况,但是如果要分析更为详细的信息,比如要找到是什么让CPU繁忙、某些方法的调用次数等,还需要借助另一个工具——Android Studio中提供的CPU分析器。我们可以生成跟踪日志,然后使用 CPU 分析器导入和检查这些日志。

5.使用CPU分析器工具进行分析

在Android Studio 3.2之前,一般会使用Traceview,但是由于Traceview日志记录无法很好地处理线程(如果线程在分析期间退出,不会发出线程名称(在 Android 5.1 及更高版本中已解决此问题);虚拟机会重复使用线程 ID。如果在一个线程停止时另一线程开始,这两个线程可能会获得同一 ID),所以已经在Android Studio 3.2中被弃用,取而代之的是CPU 性能剖析器。
CPU 性能剖析器不仅能够以图形的形式显示跟踪日志,更包含了Systrace的工作,因此,在Android Studio 3.2以后就可以使用CPU 性能剖析器完成这两项工作了。
我们接着Systrace的工作来做,生成一个跟踪日志。

5.1使用 Debug API 记录 CPU 活动

如果在开发过程中出现不好复现的问题,可以在代码中添加跟踪语句,如下所示:

// Starts recording a trace log with the name you provide. For example, the
// following code tells the system to start recording a .trace file to the
// device with the name "sample.trace".
Debug.startMethodTracing("sample");
...
// The system begins buffering the generated trace data, until your
// application calls <code><a href="/reference/android/os/Debug.html#stopMethodTracing()">stopMethodTracing()</a></code>, at which time it writes
// the buffered data to the output file.
Debug.stopMethodTracing();

在开始监控的地方调用startMethodTracing方法,在需要结束的地方调用stopMethodTracing方法,系统就会在~/sdcard/ 目录中生成trace文件,这个文件包含二进制方法跟踪数据,以及一个包含线程和方法名称的映射表。在进行跟踪的时候不要忘了在AndroidManifest.xml中个加入

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

权限。
我们来举个例子进行详细说明。

public class TraceSampleActivity extends AppCompatActivity {
   

    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_trace_sample);
        //开始跟踪,并且指定生成名为sample的.trace文件
        Debug.startMethodTracing("sample");
        initView();
    }
    private void initView(){
   
        try {
   
            Thread.sleep(1000);
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }
    }

    @Override
    protected void onStop() {
   
        super.onStop();
        //结束监控
        Debug.stopMethodTracing();
    }
}

我们使用了一个简单的例子来生成trace文件,然后将这个文件导出到桌面。这个trace文件的位置如下图所示:
在这里插入图片描述

5.2导入跟踪数据

①打开 CPU 性能剖析器:依次选择 View > Tool Windows > Profiler 或点击工具栏中的 Profile 图标在这里插入图片描述
在这里插入图片描述
②在性能剖析器的 Sessions 窗格中点击 Start new profiler session 图标在这里插入图片描述 ,然后选择 Load from file。
在这里插入图片描述
可以看到分为了两部分,分别是左面的时间片面板和右面的分析面板。
时间面板放大,之后将鼠标指针悬停在某个线程上,可以看见更详细的信息。
在这里插入图片描述
一般我们会查看色块的长度,然后对明显比较长的方法重点去关注。单击色块可以在右面的分析面板查看具体分析。
更详细的操作可以查看谷歌开发者文档

6.使用布局优化工具进行分析

6.1使用布局检查器和布局验证工具调试布局

在Android Studio 3.1之前,一般会使用Hierarchy Viewer分析布局,但是在Android Studio 3.1开始,Hierarchy Viewer则被弃用,改为了布局检查器和布局验证工具。
使用Android Studio中的布局检查器,可以将应用布局与设计模型进行比较、显示应用的放大视图或3D视图,以及在运行时检查应用布局的细节。如果布局是在运行时(而不是完全在XML中)构建的并且布局行为出现异常,该工具会非常有用。
使用布局验证,可以在不同的设备和显示配置(包括可变字体大小或用户语言)上同时预览布局,以便轻松测试各种常见的布局问题。

  • 布局检查器
    1.打开布局检查器
    a.在连接的设备或模拟器上运行应用;
    b.依次点击 Tools > Layout Inspector,如下图所示,布局检查器将显示以下内容:
    在这里插入图片描述
    标号1:Component Tree:布局中视图的层次结构。
    标号2:Layout Display:按照应用布局在设备或模拟器上的显示效果呈现布局,并显示 每个视图的布局边界。
    标号3:布局检查器工具栏:布局检查器的工具。
    标号4:Attributes:所选视图的布局属性。
    2.选择视图
    如要选择某个视图,可以在Component Tree或Layout Display中点击该视图,所选视图的所有布局属性都会显示在Attributes面板中,如上图所示。
    3.隔离视图
    如要使用复杂的布局,我们可以隔离各个视图,以便只有布局的一部分显示在 Component Tree 中并呈现在 Layout Display 中。在 Component Tree 中右键点击该视图,然后选择 Show Only Subtree 或 Show Only Parent。如需返回完整视图,右键点击该视图,然后选择 Show All。
    4.隐藏布局边框和视图标签
    如果想要隐藏布局元素的边界框或视图标签,点击Layout Display顶部的View Options图标在这里插入图片描述,然后切换Show Borders或Show View Label。
    5.将应用布局与参考图像叠加层进行比较
    如果需将应用布局与参考图像(如界面模型)进行比较,可以在布局检查器中加载位图图像叠加层。
    a.如需加载叠加层,点击布局检查器顶部的 Load Overlay 图标在这里插入图片描述。系统会缩放叠加层以适合布局。
    b.如需调整叠加层的透明度,使用 Overlay Alpha 滑块。
    c.如需移除叠加层,点击 Clear Overlay 图标在这里插入图片描述
    6.实时布局检查器
    实时布局检查器可以在应用被部署到搭载 API 级别 29 或更高版本的设备或模拟器时,提供应用界面的完整实时数据分析。
    要想启用实时布局检查器,需要进行如下操作:依次转到 File > Settings > Experimental,勾选 Enable Live Layout Inspector 旁边的框,然后点击 Layout Display 上方 Live updates 旁边的复选框。
    实时布局检查器包含动态布局层次结构,可随着设备上视图的变化更新 Component Tree 和 Layout Display。
    此外,使用属性值解析堆栈,也可以调查资源属性值在源代码中的来源位置,并按照属性窗格中的超链接导航到其位置,如下图所示。
    在这里插入图片描述
    最后,Layout Display 可在运行时对应用的视图层次结构进行高级 3D 可视化。如需使用该功能,只需在实时布局检查器窗口中点击相应布局,然后拖动鼠标旋转该布局即可。如需展开或收起布局的图层,使用Layer Spacing滑块。
  • 布局验证工具
    “布局验证”是一款可视化工具,用于同时预览不同设备中及采用不同配置的布局,有助于我们在此过程的早期发现布局存在的问题。如需使用该功能,在打开布局文件后,点击IDE窗口右上角的Layout Validation标签页:
    在这里插入图片描述
    如需在可用的配置集之间切换,可以从“Layout Validation”窗口顶部的下拉列表中选择以下某个配置:①Pixel Devices;②自定义;③色盲;④字体大小
    在这里插入图片描述
    1.Pixel Devices
    预览布局在 Pixel 设备上的显示效果,也是默认的选项,我们一进来看见的效果就是这个。
    2.自定义
    从各种设置(包括语言、设备或屏幕方向)中进行选择自定义要预览的显示配置:
    在这里插入图片描述
    3.色盲
    为了方便色盲用户使用我们的应用,需要通过常见色盲类型的模拟验证布局:
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值