Android性能优化

App性能优化


一、启动速度

1.启动方式

1. 冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动。

2. 热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,这个方式叫热启动。


2.特点


1. 冷启动:冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类,再创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。
2. 热启动:热启动因为会从已有的进程中来启动,所以热启动就不会走Application这步了,而是直接走MainActivity(包括一系列的测量、布局、绘制),所以热启动的过程只需要创建和初始化一个MainActivity就行了,而不必创建和初始化Application,因为一个应用从新进程的创建到进程的销毁,Application只会初始化一次。


3.测量方法

 

adb shell am start -W [packageName]/[packageName.MainActivity]


1. TotalTime:应用的启动时间,包括创建进程+Application初始化+Activity初始化到界面显示。 
2. ThisTime:一般和TotalTime时间一样,除非在应用启动时开了一个透明的Activity预先处理一些事再显示出主Activity,这样将比TotalTime小。 
3. WaitTime:一般比TotalTime大点,包括系统影响的耗时。

4.优化方式


1. 在Application的构造器方法、attachBaseContext()、onCreate()方法中不要进行耗时操作的初始化,一些数据预取放在异步线程中,可以采取Callable实现。
2. 对于sp的初始化,因为sp的特性在初始化时候会对数据全部读出来存在内存中,所以这个初始化放在主线程中不合适,反而会延迟应用的启动速度,对于这个还是需要放在异步线程中处理。
3. 对于MainActivity,由于在获取到第一帧前,需要对contentView进行测量布局绘制操作,尽量减少布局的层次**(参照界面性能)**,考虑StubView的延迟加载策略,当然在onCreate、onStart、onResume方法中避免做耗时操作。

 
二、渲染优化


1 渲染机制


​    Android系统每隔16ms发出VSYNC信号,触发对UI进行渲染,那么整个过程如果保证在16ms以内就能达到一个流畅的画面。


而我们编写App的时候,有时会感觉界面卡顿,尤其是自定义View的时候,大多数是因为布局的层次过多,存在不必要的绘制,或者onDraw等方法中过于耗时,或者频繁gc。如果操作超过了16ms就会发生下面的情况:掉帧


2 过度绘制( OverDraw)


​    Overdraw(过度绘制)描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次。在多层次的UI结构里面, 如果不可见的UI也在做绘制的操作,这就会导致某些像素区域被绘制了多次。这就浪费大量的CPU以及GPU资源。

3 常用工具

 

3.1 Show GPU Overrdraw
按照以下步骤打开Show GPU Overrdraw的选项:设置 -> 开发者选项 -> 调试GPU过度绘制 -> 显示GPU过度绘制

蓝色,淡绿,淡红,深红代表了4种不同程度的Overdraw情况,

- 蓝色: 意味着overdraw 1倍。像素绘制了两次。大片的蓝色还是可以接受的(若整个窗口是蓝色的,可以摆脱一层)。
- 绿色: 意味着overdraw 2倍。像素绘制了三次。中等大小的绿色区域是可以接受的但你应该尝试优化、减少它们。
- 淡红: 意味着overdraw 3倍。像素绘制了四次,小范围可以接受。
- 深红: 意味着overdraw 4倍。像素绘制了五次或者更多。这是错误的,要修复它们。

我们的目标就是尽量减少红色Overdraw,看到更多的蓝色区域。
3.2 Hierarchy Viewer
​    Hierarchy View 在Android SDK里自带,它能检查布局层次结构中每个视图的属性和布局速度。它可以帮助你找到你的视图层次结构造成的性能瓶颈,帮助你简化层次、减少过度绘制。
参考:http://www.jianshu.com/p/a2ce59503224
参考:http://www.jianshu.com/p/7ac6a2b8d740


4 优化方案


- 去掉window的默认背景
  当我们使用了Android自带的一些主题时,window会被默认添加一个纯色的背景,这个背景是被DecorView持有的。当我们的自定义布局时又添加了一张背景图或者设置背景色,那么DecorView的background此时对我们来说是无用的,但是它会产生一次Overdraw,带来绘制性能损耗。去掉window的背景可以在onCreate()中setContentView()之后调用getWindow().setBackgroundDrawable(null);或者在theme中添加android:windowbackground="null";
- 去掉其他不必要的背景
- clipRect的使用
  我们可以通过[canvas.clipRect()](http://developer.android.com/reference/android/graphics/Canvas.html)来 帮助系统识别那些可见的区域。这个方法可以指定一块矩形区域,只有在这个区域内才会被绘制,其他的区域会被忽视。这个API可以很好的帮助那些有多组重叠 组件的自定义View来控制显示的区域。同时clipRect方法还可以帮助节约CPU与GPU资源,在clipRect区域之外的绘制指令都不会被执行,那些部分内容在矩形区域内的组件,仍然会得到绘制。
- ViewStub
  ViewStub称之为“延迟化加载”,程序无需显示ViewStub所指向的布局文件,只有在特定的某些较少条件下,此时ViewStub所指向的布局文件才需要被inflate,且此布局文件直接将当前ViewStub替换掉,具体是通过viewStub.infalte()或viewStub.setVisibility(View.VISIBLE)来完成;
- Merge标签
  Merge标签可以干掉一个view层级。Merge的作用很明显,但是也有一些使用条件的限制。有两种情况下我们可以使用Merge标签来做容器控件。第一种子视图不需要指定任何针对父视图的布局属性,就是说父容器仅仅是个容器,子视图只需要直接添加到父视图上用于显示就行。另外一种是假如需要在LinearLayout里面嵌入一个布局(或者视图),而恰恰这个布局(或者视图)的根节点也是LinearLayout,这样就多了一层没有用的嵌套,无疑这样只会拖慢程序速度。而这个时候如果我们使用merge根标签就可以避免那样的问题。另外Merge只能作为XML布局的根标签使用,当Inflate以开头的布局文件时,必须指定一个父ViewGroup,并且必须设定attachToRoot为true。
- 将可重复使用的组件抽取出来并用 `</include>` 标签进行重用。如果应用多个地方的 UI 用到某个布局,就将其写成一个布局部件,便于各个 UI 重用。
- 尽量避免使用 layout*weight 属性。使用包含 layout*weight 属性的线性布局 `LinearLayout` 每一个子组件都需要被测量两次,会消耗过多的系统资源。


三、APK大小优化

1 APK的结构


在讨论如何减小apk大小之前,理解apk的结构很有必要。一个APK文件包括一个ZIP 文件,该ZIP包含app的所有文件。包括java 字节码文件,资源文件和一个包含了编译后的资源文件。APK包含以下目录:
- META-INF/:包含了CERT.SF 和 CERT.RSA 签名文件, 以及 MANIFEST.MFmanifest 文件.
- assets/: 包含了app的assets,app可以通过 AssetManager 对象获取到这些资源
- res/: 包含了那些没有被编译到 resources.arsc的资源
- lib/: 包含了用于软件处理器的编译代码,该目录包含一个子目录,针对不同平台: armeabi, armeabi-v7a, arm64-v8a, x86, x86_64, and mips.
  一个APK也包含了下面的文件,但只有 AndroidManifest.xml 是强制性的
- resources.arsc:
  包含了编译后的资源。该文件包含了 res/values/文件夹下的所有XML内容。打包工具抽取了XML内容,将它编译成二进制格式,并且进行了压缩。该内容包括language strings和styles,以及未直接包含在resources.arsc 文件中的内容路径。比如layout文件和图片。
- classes.dex:
  包含可以被Dalvik/ART 识别,以dex文件格式编译后的代码
- AndroidManifest.xml:
  包含了Android核心mainfest文件。该文件罗列了app名字,版本,访问权限,和引用的library文件。该文件采用二进制XML格式。


2 优化方式


- 移除无用资源
- 最小化使用Libraries中的资源
- 只支持特定的分辨率
- 减少动画帧数
- 减少资源
- 压缩PNG文件
- 使用矢量图形

参考
http://www.lightskystreet.com/2016/10/17/android-optimize-apk/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值