Android 启动优化

说到App优化,首先考虑到的就是App启动的优化,要想加速启动首先要先了解App启动的过程。接下来我们首先简要分析一下App冷启动是怎样一个流程。

应用进程不存在的情况下,从点击桌面应用图标,到应用启动(冷启动),大概会经历以下流程:
1.Launcher startActivity
2.AMS startActivity
3.Zygote fork 进程
4.ActivityThread main()
 4.1. ActivityThread attach
 4.2. handleBindApplicatio
 4.3. attachBaseContext
 4.4. installContentProviders
 4.5. Application onCreate

  1. ActivityThread 进入loop循环
  2. Activity生命周期回调,onCreate、onStart、onResume...

其中App能够干预到的只有 4.3,4.5,6这三个步骤,其它的对App来说是黑盒的,App是不能控制的(除非设备Root,你可以干预其它流程,或者在设备启动后直接后台初始化自己的进程), 我们的优化也是主要针对这三个步骤进行优化。

1. attachBaseContext优化

首先我们来看 attachBaseContext(),此方法我们一般会用作对多MultiDex做处理,我们知道Android5.0以前是不支持MultiDex的,需要在此方法中进行
MultiDex.install(this) 安装多dex,这个过程中会对我们的Apk进行解压缩找到dex文件列表,然后通过反射把dex文件放进虚拟机ClassLoader中的dex数组中,这个过程因为有解压缩apk以及反射操作是比较耗时的。

既然这里是耗时的我们是否可以去开启子线程去执行MultiDex.install(),答案是否定的,假设一个场景,我们开线程异步加载,主线程继续执行后面的初始化ContentProviders或者 Application的onCreate()方法中如果有需要用到非主dex文件的Class而这时候子线程的MultiDex.install()还没有完成安装就会造成 NoClassDeFound异常,所以此方法是行不通的。具体优化方案见:https://www.cnblogs.com/renhui/p/11716975.html

总结:MulitiDex.install主要针对5.0以下的设备(不包含5.0),目前市面上的设备基本上已经没有5.0以下的设备了,所以这部分优化能涵盖的设备已经很少了,5.0以上是默认支持MulitdDex的,这个方法什么都不用做,直接返回。

image.png

2. Application onCreate()优化

终于到了我们喜闻乐见的onCreate了,这一步也是我们优化的主要战场,通常在这一步中我们会做一些三方sdk以及自有业务的一些初始化,这些初始化工作其实并不是一开始就需要的,我们完全可以做一些懒加载处理或者异步加载。那怎样判断Application onCreate()方法的执行耗时呢?
最Low的办法就是在onCreate的方法入口 和 方法出口各自加时间戳判断,但是这只能判断整个方法的执行时间,但假如我们的onCreate的方法中有很多个sdk要初始化呢,只能是每个sdk初始化前后各需要加时间戳判断,这样写起来就太费劲了。还好Android给我们提供了很多性能测试的方法。接下来我们介绍一下 Debug.startMethodTracing()与Debug.stopMethodTracing(),把这个方法加入Application的onCreate方法开始和结束处会默认生成每个方法的堆栈信息及调用时间文件保存到sd卡中,然后再通过AS的 profile工具来查看详细信息。
代码如下:

    @Override
    public void onCreate() {
        super.onCreate();
        Debug.startMethodTracing("im_ana");
        initIm();// 初始化Im SDK
        Debug.stopMethodTracing();
    }

startMethodTracing()的参数是生成堆栈信息的文件名,扩展名为.trace,生的文件会保存在 sdcard/Android/data/{$packageName}/file/ 目录下。(注意:这里因为要对sd卡读写需要先授权,还有另外一个问题,堆栈文件信息默认大小为10M,如果中间需要监控的方法太多会导致信息收集不全,这时候可以在startMethodTracing()方法中配置堆栈文件的bufferSize处理)。把生成的文件导出来直接拖到AndroidStudio中即可以显示可视化的方法堆栈信息。见下图:

image.png

这里可以看到方法的调用堆栈以及每个方法的调用时间,有了这些信息,我们就可以轻松判断到底是哪些方法执行时间过长了。就可以选择哪些需要开启线程异步加载或者懒加载执行了,目前Application的onCreate()优化方法介绍完成了,如果有哪里写的不对还请看到的大神指出来,感激不尽!

3. 首屏Activity优化

3.1 首屏主题优化

一般我们冷启动App时,首屏Activity首先会弹出来然后黑屏或白屏一段时间这段时间其实是在执行上面说到的启动流程。系统默认给我们设置的主题样式,既然是主题样式我们就可以替换首屏Activity的主题来替换黑白屏,自定义主题样式如下:

 

在windowBackground中设置drawable可以是我们自己的图片,这样就可以启动时显示我们配置的图片信息,防止黑白屏的尴尬。

这里并没有提高我们App的启动时间,只是在体验是做了优化。

3.2 布局文件加载优化

  1. 布局文件加载要尽量减少层级,能用FrameLayout或者LinearLayout完成的就不要用RelativeLayout或者ConstraintLayout,因为RelativeLayout会执行两次measure测量。还要合理运用include,merge,ViewStub 来进行层级缩减或懒加载来提高页面渲染速度。

  2. 我们知道Android布局文件是能过读取xml资源文件,然后通过反射生成Android的View这中间有两个步骤是耗时操作,一个是读取xml进行的IO操作,一个是反射生成View的操作,这两个步骤都是在运行时同步的操作,这两个流程都有可能造成性能方面的问题。针对此问题目前有三方解决方案 X2C ,其原理是通过apt工具在编译期把xml布局文件生成 Java类。X2C开源库地址:https://github.com/iReaderAndroid/X2C

3.剩下的问题就是不要在生命周期方法中执行耗时操作,这样会导致UI掉帧及ANR的问题。

你可能感兴趣的:(Android 启动优化)