🔥 Android性能优化指标 🔥
🔥 包体积优化 🔥
安装包的大小会影响用户的安装率,如果一个包的太大,用户安装的意愿会大大降低。
经过包分析可以看到,安装包最大的部分是资源和第三方库,而减少apk包体积大小,主要处理的就是res下的资源文
件、.class文件。优化的思路如下:
1、压缩图片大小,统一使用webp格式
2、尽可能地减少本地资源,考虑从服务端拉取图片、Lottie动画、so库等资源
3、利用Lottie替换帧动画
4、开启混淆删除无用代码
🔥 启动优化 🔥
启动优化一般分为三种情况:冷启动、热启动和页面跳转。
1、冷启动:应用首次启动所花费的时间
2、热启动:应用非首次启动所花费的时间
3、页面跳转:应用界面切换所花费的时间
我们可以使用如下的命令来查看冷启动所耗费的时间。
//启动应用时间 adb shell am start -W -n package/activity //关闭应用 adb shell am force-stop package
可以使用埋点和友盟U-APM来获取启动数据。
这里有三个指标:ThisTime、TotalTime和WaitTime,含义如下:
1、ThisTime:最后一个Activity启动耗时
2、TotalTime:所有Activity启动耗时
3、WaitTime:AMS启动Activity的总耗时
目标:
一般来说,一个体验良好的APP,冷启动应该控制在2s/3s以内,热启动控制在1s以内。对比了一些蔚来和小鹏,平均的启动时间在 2s 左右,因此,在启动优化方面,我们也需要向 2s 看齐。
🔥 渲染优化 🔥
Android 应用体验是否良好的一个重要标准就是,应用是否流畅、是否存在卡顿、丢帧现象,而这些都可以通过 60fps 有关。如果页面的一帧没法在16ms完成渲染,就可能导致丢帧或者卡顿的现象。
通常,我们可以使用下面的命令来查看某个页面的FPS 数据。
adb shell dumpsys SurfaceFlinger --latency activity
还可以使用下面的命令来获取FPS和GPU相关的数据。
adb shell dumpsys gfxinfo 包名
出现丢帧和卡顿的原因 :
往往是 layout 布局太过复杂,或 UI上有层叠太多的绘制单元。我们可以通过手机设置里面的【开发者选项】->【显示过渡绘制区域】来观察 UI 上的 Overdraw 情况。
为了实现60fps的渲染目标,应该遵循如下优化措施:
1、耗时操作放到子线程进行处理,主线程只负责渲染
2、SDK采用懒加载方式,需要时或者空闲时加载,不需要时可不必加载
3、线上环境避免打印日志
4、优化view视图渲染时间
优化复杂布局 :
考虑使用ConstraintLayout约束布局,减少视图渲染的层级。如果不是很复杂,则使用LinearLayout。其他措施,如巧用ViewStub、merge标签。以及使用Android Studio自带的Android Device Monitor工具查看布局情况。
优化布局,特别是处理红色部分的过渡渲染问题。
🔥 内存优化 🔥
Android分配个应用的大小是有限制,且在设备出厂时就已经确定,单个应用可用的最大内存的配置位于/system/build.prop文件中的dalvik.vm.heapgrowthlimit配置项。
在Android系统中,每个APP内存包括两部分:共享内存和私有内存。在行业内,我们通常会使用PSS(USS+共享的内存)来判断APP的内存开销,查看的命令如下。
adb shell dumpsys meminfo 应用包名
虽然Android使用的JVM具有内存管理(自动回收)的能力,但是不合理的使用内存也可能导致导致应用出现异常,如常见的OOM、内存泄漏、内存抖动等引发的崩溃、卡顿等现象。 针对内存优化,主要有以下几点:
OOM(内存溢出)
当应用申请内存发现超出了JVM的最大限制时候,就会抛出内存溢出异常,引发程序崩溃。引发OOM常见原因有:内存泄漏的累积导致无法申请更多内存、创建大内存对象(如大容量数组、载入大的文件、载入大的图片等)。
内存泄露
一个对象的超出了其生命周期,导致JVM无法回收。常见的内存泄露场景有:
1、单例持有引起的内存泄漏,如单例持有activity、context、view、drawabl等
2、静态变量引起的内存泄漏,如静态变量持有activity、context、view、drawabl等
3、非静态内部类引起的内存泄漏,非静态内部类会隐式持有外部类实例
4、匿名内部类引起的内存泄漏,如handler、线程匿名内部类runnable、callback等
5、资源未释放引起的内存泄漏,如读写文件没有关闭、网络流操作没有关闭、Bitmap没有释放等
6、广播没有及时取消注册
内存抖动
内存抖动是因为在频繁的创建、回收对象,引发的频繁GC,进而影响主线程,最终导致卡顿现象。
目标
在开发环境,我们可以打开Android Studio自带的Memory Profiler内存分析器来进行内存分析。
选择内存分析器中的Capture heap dump,点击下方的Record按钮,就开始捕获堆转储了,而此步可以检测出内存泄漏问题。
🔥 CPU优化 🔥
CPU优化,大多数开发者都不会太关注,但是优化应用的 CPU 使用率能带来诸多好处,如更顺畅的用户体验,以及延长设备电池续航时间。在正式介绍之前,我们先来看两条命令。第一条是用来查看各线程cpu占用情况。
adb shell top
使用下面的命令打印进程下线程信息 :
adb shell ps -t -p -c | findstr u0_a60
CPU相关的内容,同样可以使用CPU Profiler 进行分析。
🔥 网络优化 🔥
Android 网络优化方法主要涉及网络测试工具、线上网络监控方案、流量优化方案和质量优化方案等几个方面。
其中,常见的网络测试工具有 Network Profiler、Charles和Stetho,线上网络监控方案有OkHttp 的 EventListener、NetworkStatsManager 和 TrafficStats,流量优化方案有数据缓存、数据压缩和图片压缩,质量优化方案有HttpDns 优化、协议版本优化(如Protocol Buffer)。
开启Gzip压缩,减少流量传递消耗
IP直连与HttpDns,减少DNS解析
根据网络使用不同分辨率的图片,不行的话,可以统一使用WebP格式
升级网络协议,开启Http2的多路复用策略
网络优化要做线下测试和线上监控,在做线下测试时,要测试不同的网络类型下客户端的使用体验,比如切换 Wifi 和流量,还要测试不同的网络状态,比如弱网测试和无网测试。并且,在做线下测试时,要把测试周期拉长一些,因为客户端中有的网络请求不是实时上报的,测试网络的时候测久一点才能测出问题。Network Profiler 是 Android Studio 提供的一个网络分析工具,在 Network Profiler 中包含了连接视图、线程视图、请求概览、响应信息、请求信息以及调用栈等数据,在连接视图中可以看到请求的内容类型、请求状态和请求耗时等信息,我们可以使用它来分析一些耗时的问题。
使用Charles模拟弱网环境,针对3G等弱网环节进行相应的适配(服务器接口)。
检查Android的网络配置,开启多路复用逻辑
排查耗时长的接口,针对性的进行优化
图片等资源,使用Webp(链路支持)
开启OkHttp的缓存,优化无网的体验
🔥 电量优化 🔥
可以借助Android Studio自带的能耗性能剖析器进行分析,能耗性能剖析器会监控 CPU、网络无线装置和 GPS 传感器的使用情况,并直观地显示其中每个组件消耗的电量。
点击 Energy 时间轴中的任意位置以打开能耗性能剖析器。检查后台任务和定时任务 .
避免频繁进行网络请求,和组件的生命周期进行绑定
避免任务被频繁执行,可以等任务形成一定数量时再一起执行
避免应用频繁唤醒屏幕
避免后台长时间获取 WakeLock、WIFI 和蓝牙的扫描
避免轮询请求,需要轮询的使用AlarmManager