《Android群英传》——个人读书笔记
10.1 布局优化
10.1.1 Android UI 渲染机制
Android系统通过 VSYNC信号 触发对UI的渲染、重绘。其时间间隔在16ms(1000ms显示60帧画面的单位时间)以内。超过16ms就会造成 丢帧现象 ,即当前该重绘的帧被未完成的逻辑阻塞。
可通过开发者选项打开检测UI渲染时间的工具。每一条柱状图包含三个部分:
- 蓝色:测量绘制Display List的时间
- 红色:OpenGL 渲染Display List所需的时间
- 黄色:CPU等待GPU处理的时间
中间的绿色横线代表VSYNC时间(16ms),需要尽量将所有条形图都控制在这条绿线之下。
10.1.2 避免 Overdraw
- Overdraw——过度绘制,过度绘制会浪费很多的CPU、GPU资源。
10.1.3 优化布局层级
- 系统对View的测量、布局以及绘制时,都是通过遍历View树来进行操作的。
因此优化布局的第一个方法就是 降低View树的高度 Google API 建议不超过10层。
10.1.4 避免嵌套过多无用布局
10.1.4.1 使用<include>标签重用Layout
10.1.4.2 使用<ViewStub>实现View的延迟加载
- 一个轻量级的组件,不仅不可见,且大小为0
- 引用方式与 include 相同,但此时引用的布局并没有显示出来,显示的方式有两种:
1)VISIBLE
mViewStub.setVisiblility(View.VISIBLE);
2)inflate
View inflateView = mViewStub.inflate();
一旦<ViewStub>被设置为可见或是被inflate,<ViewStub>就不存在了,取而代之的被inflate的Layout。并将这个Layout的ID重新设置为<ViewStub>中通过 android:infaltedId 属性所指定的ID,这也是为什么两次调用inflate方法会报错的原因。
- <ViewStub>标签 与设置 View.GONE 的区别
共同点都是在初始时不会显示布局,但是 标签 只会在显示时,才去渲染这个布局,而View.GONE在初始化布局树的时候就已经添加在布局树上了。所以相比之下,标签的效率更高。
10.1.5 Hierarchy Viewer
Hierarchy Viewer 无法在加密过的真机设备上使用。
- Google大神 Runmain Guy 提供了一个开源项目 View Server 可以在真机上使用 Hierarchy Viewer github地址
10.2 内存优化
10.2.1 什么是内存
由于Android应用的沙箱机制,每个应用分配的内存大小是有限制的,内存太小则会触发 LMK——Low MeMary Killer机制
-
内存 通常情况下就是我们所说的手机的 RAM
包含五个部分: - 1)寄存器(Registers)——速度最快的存储场所(因为寄存器位于处理器内部,在程序中无法控制)。
- 2)栈(Stack)——存放基本类型的数据以及对象的引用,但对象本身并不存放在栈中,而是存放在堆中。
- 3)堆(Heap)——存放由 new 创建的对象和数组。在堆中分配的内存,由java虚拟机的自动回收器(GC)来管理。
- 4)静态存储区域(Stack Field)——指在固定的位置存放应用程序运行时一直存在的数据,java在内存中专门划分了一开静态存储区域来管理一些特殊的数据变量,如静态的数据变量。
- 5)常量池(Constant Pool)——JVM虚拟机必须为每个被装载的类型维护一个常量池。常量池就是该类型所用到的常量的一个有序的集合,包含直接常量(基本类型,String)和对其他类型、字段和方法的符号引用。
当定义一个变量,Java虚拟机就会在栈中为该变量分配内存空间,当该变量作用域结束后,这部分内存空间会马上被用作新的控件进行分配。如果使用new的方式创建一个变量,那么就会在堆中为这个对象分配内存空间,即使该对象的作用域结束,这部分内存也不会立即被回收,而是等待系统GC进行回收。
所谓的内存分析,就是分析Heap中的内存状态。
10.2.2 获取Android系统内存信息
10.2.2.1 Process Stats
- 系统内存监视服务
10.2.2.2 Meminfo
- 内存监视工具
10.2.3 内存回收
- Java创建了垃圾收集器线程(Garbage Collection Thread)来自动的进行资源管理。从而降低了开发人员对内存管理的繁杂工作。
10.2.4 内存优化实例
10.2.4.1 Bitmap实例
- Bitmap是造成内存占用过高甚至OOM的最大威胁。
- 使用Bitmap的小技巧:
1)使用适当分辨率和大小的图片
2)及时回收内存 —— Android3.0之前,使用完需调用 bitmap.recycle() 方法进行内存的释放。3.0之后,Bitmap被放到了 堆 中,其内存由 GC 管理,不需要再手动进行释放。
3)使用图片缓存 —— 通过 内存缓存(LruCache) 和 硬盘缓存(DiskLruCache) 可以更好的使用Bitmap
10.2.4.2 代码优化
- 从代码的实现方式上,进行优化:
1)对常量使用 static 修饰符
2)使用静态方法(静态方法比普通方法提高约15%的访问速度)
3)减少不必要的成员变量
4)减少不必要的对象。使用基础类型回避使用对象更加节省资源
5)尽量不要使用枚举、少用迭代器
6)对Cursor、Receiver、Sensor、File等,要非常注意对他们的创建、回收与注册、解注册。
7)避免使用IOC框架。IOC 通常使用注解、反射来进行实现,Java已对反射的效率做了很好的优化,但是大量的使用反射依旧会造成性能的下降。
8)使用RenderScript、OpenGl 来进行非常复杂的绘图操作
9)使用SurfaceView 来替代 View 进行大量、频繁的绘图操作
10)尽量使用视图缓存,而不是每次都执行inflate()方法解析视图
10.3 Lint 工具
- 它是AS中集成的一个Android代码提示工具
10.4 使用 Android Studio 的 Memory Monitor 工具
- AS自带的一个内存监视工具,可以帮助我们进行内存的分析。
10.5 使用 TraceView 工具优化 APP 性能
- Android下可视化性能调查工具
10.5.1 生成 TraceView 日志的两种方法
一种是利用Debug类帮助我们生成日志文件,另一种是利用 Android Device Monitor 工具辅助生成日志文件。
10.5.1.1 通过代码生成精确范围的 TraceView 日志
- 开启监听:Debug.startMethodTracing()
- 关闭监听:Debug.stopMethodTracing()
TraceView 的日志会保存在 “/sdcard/dmtrace.trace” 目录下,所以需要在Mainifest文件中添加如下权限:
<uses-permission
android:name="anroid.permission.WRITE_EXTERNAL_STORACE">
- 当被监听的内容执行完毕之后,通过ADB命令到导出本地:
adb pull/sdcard/trace_log.trace/local/LOG/
10.5.1.2 通过 Android Device Monitor 生成 TraceView 日志
TraceView 提供了两种监听方式:
- 整体监听
跟踪每个方法执行的全部过程,但资源消耗很大 - 抽样监听
按照指定的频率抽样调查。执行时间长,获取样本数据准确。
10.5.2 打开 TraceView 日志
对于导出的 TraceView 日志文件,可以使用SDK中的 “sdk\tools\traceview.bat” 工具来打开。或者使用ADM工具打开。
10.5.3 分析 TraceView 日志
10.5.3.1 时间轴区域
显示不同线程在不同时间段内的执行情况,其中的 每一行 都代表了一个独立的线程。不同的色块 代表不同的执行方法,色块的长度 代表方法所执行的时间。
10.5.3.1 Profile 区域
区域内显示,你选择的色块所代表的方法在该色块所处的时间段内的性能分析。
- Incl CPU Time 某方法占用CPU的时间
- Excl CPU Time 某方法本身(不包括子方法)占用CPU的时间
- Incl Real Time 某方法真正执行的时间
- Excl Real Time 某方法本身(不包括子方法)真正执行的时间
- Calls+RecurCalls 调用次数+递归回调的次数
每个时间都包含两列,一个是实际的时间,另一个是百分比。分析的时候通常从 Incl CPU Time 和 Calls+RecurCalls 开始进行分析,对占用时间长的方法中点分析,如果占用时间长,并且 Calls+RecurCalls 次数又少,那么就可以列为怀疑对象了。
10.6 使用MAT工具分析App内存状态
- MAT——Memory Analyzer Tool
10.6.1 生成 HPROF 文件
10.6.2 分析 HPROF 文件
10.7 使用 Dumpsys 命令分析系统状态
- 使用 Dumpsys 命令可以列出 Android 系统相关的信息和服务状态
- 使用 adb shell dumpsys + 指定参数 就可以获得相应的信息,例如获取 activity 栈的详细信息:adb shell dumpsys activity
- 常用的 Dumpsys 参数:
参数 | 含义 |
---|---|
activity | 显示所有的Activity栈的信息 |
meminfo | 内存信息 |
battery | 电池信息 |
package | 包信息 |
wifi | 显示Wi-Fi信息 |
alarm | 显示alarm信息 |
procstats | 显示内存状态 |
网友评论