学习了解要点
一 布局优化
系统在渲染UI界面的时候将消耗大量的资源,一个好的UI不仅应该有良好的视觉效果,更应有良好的使用体验,因此布局优化就显得非常重要。
1.1Android UI渲染机制
人眼所感觉的流畅画面,需要的帧数达到40帧每秒到60帧每秒,PC游戏最佳fps在60fps左右,这是评价显卡性能高低的标准之一。
在Android中,系统通过VSYNC信号触发对UI的渲染,重绘,其时间间隔是16ms。这个16ms其实就是1000ms中显示60帧画面的单位时间,即1000/60.如果系统每次渲染的时间都保持在16ms之内。如果不能在16ms内完成绘制,那么就会造成丢帧现象,即当前该重绘的帧被未完成的逻辑阻塞。
例如一次绘制任务耗时20ms,那么在16ms系统发出VSYNC信号时就无法绘制,该帧就被丢弃,等待下次信号才开始绘制,导致16*2ms内都显示同一帧画面,这就是画面卡顿的原因
1.2避免Overdraw
Overdraw,过度绘制会浪费很多的CPU,GPU资源,例如系统默认会绘制Activity的背景,而如果再给布局绘制了重叠的背景,那么Activity的背景就属于无效的过度绘制—Overdraw。Android系统在开发者选项中提供了一个检测工具——“Enable GPU Overdraw”。激活后可以通过界面上的颜色判断Overdraw的次数。
开发者通过这个工具可以查看绘制次数,从而尽量优化绘图层次,尽量增大蓝色区域,减少红色区域。
1.3优化布局层级
在Android中,系统对View进行测量,布局,绘制时,都是,通过对View树的遍历来进行操作的。如果一个View树高度太高,就会严重影响测量,布局和绘制的速度,因此优化布局的第一个方法就是降低View树的高度,Google也在其API文档中建议View树的高度不宜超过10层。
1.4避免嵌套过多的无用布局
嵌套布局会让View树变高,布局时应避免这情况
1.4.1使用< include>标签重用Layout
原模板组件width和height设为0,用的时候使用< include>,在这个标签里重新设置width和height。
1.4.2使用< ViewStub>实现View的延迟加载
< ViewStub>是一个轻量级的组件,它不仅不可视,而且大小为0.
两种方法重新显示这个在布局中使用ViewStuv包裹的View
先findViewById找到这个组件
不管哪种方式展开ViewStub一旦被设置为可见或是被Inflate了,< ViewStub>就不存在了,取而代之的是被Inflate的Layout,并将这个LayoutID重新设置为< ViewStub>中通过android:inflatedId属性所设定的Id,也因此如果调用两次Inflate方法会报错.
ViewStub只有在显示时才会去渲染整个布局,而View.GONE,在初始化的时候就已经添加在布局树上了,相比之下,ViewStub标签都得布局具有更高的效率。
1.5Hierarchy Viewer
Hierarchy Viewer无法在真机上使用,只能在工厂的Demo机和模拟机上使用,即非加密过的设备
开源项目View Server可以让普通手机也能使用Hierarchy Viewer
https://github.com/romainguy/ViewServer
Hierarchy位于sdk\toos目录下,在命令行输入hierarchyviewer.bat启动程序
个人在网上随便看了篇布局优化工具Hierarchy Viewer
二:内存优化
2.1什么是内存
由于Android应用的沙箱机制,每个应用所分配的内存大小是有限度的,内存太低就会触发LMK——Low Memory Killer机制。通常情况下我们所说的内存是手机的RAM,它包括以下几个部分。
堆和栈的区分最容易搞错。
当定义一个变量,Java虚拟机就会在栈中为该变量分配内存空间,当该变量作用域结束后,这部分内存空间会马上被用作新的空间进行分配。如果使用new的方式创建一个变量,那么就会在堆中为这个变量分配内存空间,即使该对象的作用域结束,这部分内存也不会立即被回收,而是等待系统GC进行回收。堆的大小随着手机的不断发展二不断变大。在程序中可以使用以下代码来获取堆的大小,所谓内存分析,正是分析Heap中的内存状态。
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
int heapSize = manager.getLargeMemoryClass();
2.2获取系统内存信息
2.2.1Process Stats是KK上新增的一个系统内存监视服务,可以通过“Setting_Developer options-Process Stats”来开启该功能的界面。
adb shell dumpsys procstats
Meminfo也是系统上的一个重要的内存监视工具,可以在Settings-Apps Running中打开这一界面
同样也可以使用Dumpsys命令
`adb shell dumpsys meminfo
2.3内存回收
Java对于C,C++这类语言最大的优势就是不用手动管理内存资源,Java创建了垃圾收集器线程来自动进行资源的管理。大大降低了程序开发人员对内存管理的繁琐工作。
但是——Java GC是自动进行的,开发者无法控制,即使调用System.gc()方法,也只是建议系统进行GC,但系统是否采纳你的建议,说不准。JVM虽然能够自动控制GC,但是再强大的算法,也难免会存在纰漏,这就是造成内存泄漏的原因——由部分对象忘记回收。
2.4内存优化实例
1.Bitmap优化
Bitmap是造成内存占用过高甚至是OOM的最大威胁。下面是一些使用Bitmap的小技巧。
2.4.2代码优化
三:Lint工具
Android Lint工具是AS中集成的一个Android代码提示工具,它可以给你的布局,代码提供强大的帮助。如果写了冗余的XML视图代码,编辑器会给予警告。还有很多强大的功能。
四:AS的Memory Monitor工具
Memory Monitor是AS自带的一个内存监视工具,它可以很好地帮助我们进行内存实时分析
五 TraceView工具优化App性能
5.1生成TraceView日志的两种方法
一种是利用Debug类帮助我们生成日志文件,另一个是利用Android Device Monitor工具辅助生成日志文件。
5.11通过代码生成精确范围的TrceView日志
利用Debug类的方法开启TraceView监听。通过调用Debug.startMethodTracing()方法开启监听,通过调用Debug.stopMethodTracing()方法结束监听,我们可以使用这两个方法来包围要监听的代码块。
例如在onCreate()方法里调用startMethodTracing()方法来开启监听,在onDestroy()方法里使用stopMethodTracing()方法来结束监听。TraceView日志将会保存到“/sdcard/dmtrace.trace”目录下,因此需要在Mainifest文件中增加如下所示的权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
当然,也可以自定义输出日志名,路径。
要监听的内容执行完毕后,通过ADB命令将日志文件导出到本地,命令如下
adb pull /sdcard/trace_log.trace/local/LOG
5.1.2通过Android Device Monitor生成TraceView日志
Incl CPU Time —— 某方法占用CPU的时间
Excl CPU Time —— 某方法本身(不包括子方法)占用CPU的时间
Call + RecurCalls —— 调用次数+递归回调的次数
每个时间包含两列,一个是实际时间,另一个是百分比。分析的时候通常从Incl CPU Time 和 Calls+RecurCalls开始分析,对占用时间长的方法重点分析,如果占用时间长,且Calls+RecurCalls少,那就是重点怀疑对象。
六 使用MAT工具分析App内存状态
MAT分析内存
小技巧 当我们不停地点击“Cause GC”按钮时,如果“data object”一栏中的"Total Size"有明显变化,就代表可能存在内存泄漏
上面是手动查看Heap状态,下面点击“Dump HPROF File”系统会生成.hprof文件。
个人看到这里发现郭神和刘望舒写的性能优化文章不错,链接:郭 ——链接:刘。
七:使用Dumpsys命令分析系统状态
使用Dumpsys命令可以列出Android系统相关得信息和服务状态。Dumpsys得官方信息可以从如下网址获取
https://developer.android.com/studio/command-line/dumpsys
使用Dumpsys命令时,只需要输入“adb shell dumpsys+参数”,例如
adb shell dupsys activity
常用dumpsys命令
配合Linux下得shell命令,可以发挥dumpsys更加强大得作用。