Android性能优化学习笔记

参考

Android App优化, 要怎么做?

优化类型

  • App启动优化
  • 布局优化
  • 响应优化
  • 内存优化
  • 电池使用优化
  • 网络优化

工具

性能分析工具

官方

名称 作用 说明 参考
StrictMode 主要用来做主线程优化分析 一般用来检测主线程中的耗 时操作和阻塞.结果在Log console输出一些警告 官方文档
Systrace 分析UI的绘制时间, 发现耗时操作, 结合Hierarchy Viewer来提升UI性能 Systrace是一个收集和检测时间信息的工具, 它能显示CPU和时间被消耗在哪儿了, 每个进程和线程都在其CPU时间片内做了什么事儿. 而且会指示哪个地方出了问题, 以及给出Fix建议. 文档 文档 文档
Hierarchy Viewer 用来做View层级分析, 可以分析出View Tree中的性能阻塞点, 以便对症下药, 提升布局性能. Hierarchy Viewer需要Root的机器(产品机没有开启ViewServer)才可以执行.可以使用第三方的开源的ViewServer来协助我们在未Root的机器上使用Hierarchy Viewer分析. 文档 文档 文档 文档
TraceView 分析方法调用栈以及其执行时间, 优化方法执行. 一个图形化的工具, 用来展示和分析方法的执行时间. 文档 文档
Memory Monitor 用来做内存分析, 内存泄露排查的不二之选. 可以结合heap viewer, allocation tracker来分析. 内存使用检测器, 可以实时检测当前Application的内存使用和释放等信息, 并以图形化界面展示. 文档 文档 文档
Other Monitor 分别用来跟踪监测CPU,GPU和Network的使用极其变化, 可以作为网络优化, 流量优化和渲染优化等的一个指导 Android Studio的Monitor还提供了其他三个Motinor --- CPU, GPU, Network. CPU GPU Network
Systrace
Hierarchy Viewer
  • 绿色, 表示该View的此项性能比该View Tree中超过50%的View都要快.
  • 黄色, 表示该View的此项性能比该View Tree中超过50%的View都要慢.
  • 红色, 表示该View的此项性能是View Tree中最慢的.
Memory Monitor
其他

第三方

名称 作用 说明 文档
Historian 用来做电量使用分析. Google出品, 通过Android系统的bugreport文件来做电量使用分析的工具. Github
Emmagee 比官方工具更适合国人使用来做App的整体性能分析. 针对Android App的CPU, 内存, 网络, 电量等多项综合的测试分析. Github
leakcanary 集成到App中, 用来做内存问题预防最好不过了. 类似与App探针的内存泄露监测工具. Github
AndroidDevMetrics 如果你的应用使用的Dagger2, 这个就比较必要了. 一个library, 用来检测Activity生命周期执行性能, Dagger2注入性能以及帧率性能的工具. Github

APP启动优化

主要方面

  • Application的OnCreate
  • 首屏页的渲染

APP启动方式

  • 冷启动 : 系统中不存在该App进程, 需要创建APP进程 加载资源 启动mainThread 初始化首屏页
  • 热启动 : 系统中存在该App进程, 系统将后台进程切换到前台进程

Application的OnCreate

因为Application的OnCreate一般会初始化大量的集成SDK,此时需要耗费大量CPU事件.

解决方法
启动一个主进程的Service帮忙初始化SDK,推荐使用IntentService


首屏页的渲染

首屏页作为,APP启动的第一个页面.在应用切换过程中,默认出现白屏(取决于windowBackground属性).

解决方法

  • 首屏页的UI性能需要优化,并且不能是复杂的布局.
  • 首屏页设置一个非透明的背景,作为UI启动页

使用TraceView

DDMS启动

DDMS启动

代码打桩启动

// 在自己想要开始调试的地方start
Debug.startMethodTracing("filename");

// 在合适的地方stop
Debug.stopMethodTracing();

filename是dump到内存的数据文件,一般在sdcard的根目录,如果找不到可以使用find / -name filename查找

把文件拉倒本地,就可以用DDMS打开了

指标说明

  • Incl(Inclusive) Cpu Time : 方法本身和其调用的所有子方法占用CPU时间

  • Excl(Exclusive) Cpu Time : 方法本身占用CPU时间

  • Incl Real Time : 方法(包含子方法)开始到结束用时

  • Excl Real Time : 方法本身开始到结束用时

  • Call + Recursion Calls/Total : 方法被调用次数 + 方法被递归调用次数

  • Cpu Time/Call : 方法调用一次占用CPU时间

  • Real Time/Call : 方法调用一次实际执行时间

CPU Time 方法实际执行时间(不包括io等待时间)
Real Time 方法开始结束时间差(包括等待时间)

一般来说, 我们使用Real Time/Call排序来找出耗时多的方法

布局优化

Hierarchy Viewer

Hierarchy Viewer只能在root过的机器上使用,因为需要View Server.

解决方案是项目中集成ViewServer

启动

打开HV

界面

主页面
  • Window : 显示当前连接的设备和供分析的界面. 可手动选择.

  • Tree View : 树状图的形式展示该Activity中的View层级结构. 可以放大缩小, 每个节点代表一个View, 点击可以弹出其属性, 当前值, 并且在LayoutView中会显示其在界面中相应位置.Tree View是我们主要要分析的视图.

  • Tree Overview : Tree View的概览图. 有一个选择框, 可以拖动选择查看. 选中的部分会在Tree View中显示.

  • Layout View : 匹配手机屏幕的视图, 按照View的实际显示位置展示出来的框图.

参数解读

参数解读
  • 绿色 : 表示该View的此项性能比该View Tree中超过50%的View都要快.
  • 黄色 : 表示该View的此项性能比该View Tree中超过50%的View都要慢.
  • 红色 : 表示该View的此项性能是View Tree中最慢的.

如果你的界面的Tree View中红点较多, 那就需要注意了. 一般来说:

  • Measure红点, 可能是布局中嵌套RelativeLayout, 或是嵌套LinearLayout都使用了weight属性.
  • Layout红点, 可能是布局层级太深.
  • Draw红点, 可能是自定义View的绘制有问题, 复杂计算等.

Lint tool

启动

启动

分析

分析
分析

布局优化

尽量减少布局层级和复杂度

  • 尽量不要嵌套使用RelativeLayout.

  • 尽量不要在嵌套的LinearLayout中都使用weight属性.

  • Layout的选择, 以尽量减少View树的层级为主.

  • 去除不必要的父布局.

  • 善用TextView的Drawable减少布局层级

  • 如果H Viewer查看层级超过5层, 你就需要考虑优化下布局了

善用Tag

  • : 使用include来重用布局

  • : 解决布局冗余问题

  • : 不必要的布局延迟加载

ANR问题

原因

  • 5s内无法响应用户输入事件(例如键盘输入, 触摸屏幕等).
  • BroadcastReceiver在10s内无法结束.

解决方法

不能在主线程(UI线程)里面做频繁操作

分析

ANR产生时会把日志写到/data/anr/traces.txt

常见原因

  • 普通阻塞导致的ANR : 开辟单独的子线程来处理耗时阻塞事务

  • CPU满负荷 : I/O阻塞一般来说就是文件读写或数据库操作执行在主线程了, 也可以通过开辟子线程的方式异步执行

  • 内存原因 : 增大VM内存, 使用largeHeap属性, 排查内存泄露

执行在主线程的

  • Activity的所有生命周期回调都是执行在主线程的.

  • Service默认是执行在主线程的.

  • BroadcastReceiver的onReceive回调是执行在主线程的.

  • 没有使用子线程的looper的Handler的handleMessage, post(Runnable)是执行在主线程的.

  • AsyncTask的回调中除了doInBackground, 其他都是执行在主线程的.

  • View的post(Runnable)是执行在主线程的.

内存优化

Android虚拟机

  • Dalvik
  • ART

ART相比Dalvik的关键提升:

  • 引入AOT(ahead-of-time)预编译技术

  • GC效率

    • 由原来的两次GC暂停减少为一次.
    • 以较少的GC时间回收最近分配的, 短命的对象.
    • 提升GC工程学, 使并发GC更及时.
    • 压缩GC, 以减少后台内存使用和内存碎片.
  • 开发和调试

    • 支持内存/方法执行的采样分析
    • 支持更多的调试技.
    • 在Crash report中提供更多信息

Android内存管理

APP的内存分配和回收

  • HeapSize : 被限制的虚拟空间大小

  • Proportional Set Size (PSS) : APP应用运行占的内存大小

APP内存限制

  • dalvik.vm.heapstartsize : App启动后, 系统分配给它的Heap初始大小. 随着App使用可增加.

  • dalvik.vm.heapgrowthlimit : 默认情况下, App可使用的Heap的最大值, 超过这个值就会产生OOM.

  • dalvik.vm.heapsize : 如果App的manifest文件中配置了largeHeap属性, 如下.则App可使用的Heap的最大值为此项设定值

  • dalvik.vm.heaptargetutilization : 当前理想的堆内存利用率. GC后, Dalvik的Heap内存会进行相应的调整, 调整到当前存活的对象的大小和 / Heap大小 接近这个选项的值, 即这里的0.75. 注意, 这只是一个参考值.

  • dalvik.vm.heapminfree : 单次Heap内存调整的最小值.

  • dalvik.vm.heapmaxfree : 单次Heap内存调整的最大值.

获取方法

  • cat /system/build.prop
dalvik.vm.heapstartsize=8m
dalvik.vm.heapgrowthlimit=192m
dalvik.vm.heapsize=512m
dalvik.vm.heaptargetutilization=0.75
dalvik.vm.heapminfree=2m
dalvik.vm.heapmaxfree=8m
  • adb shell getprop dalvik.vm.heapsize

Android进程级别

根据进程的优先级不同而进行回收, 重要程度由高到低:

进程类型 说明
前台进程 用户当前操作所必需的进程.
可见进程 没有任何前台组件, 但仍会影响用户在屏幕上所见内容的进程
服务进程 正在运行已使用 startService() 方法启动的服务且不属于上述两个更高类别进程的进程
后台进程 包含目前对用户不可见的 Activity 的进程(已调用 Activity 的 onStop() 方法)。这些进程对用户体验没有直接影响
空进程 不含任何活动应用组件的进程。保留这种进程的的唯一目的是用作缓存,以缩短下次在其中运行组件所需的启动时间。

分析工具

Android Studio


MAT

下载地址

LeakCanary

LeakCanary Github

电量优化

battery-historian Github

你可能感兴趣的:(Android性能优化学习笔记)