Android开发Android开发经验谈

性能优化01-启动优化

2018-05-13  本文已影响127人  最爱的火

性能优化01-启动优化

一、启动定义

启动:从手指点击app图标,到第一个页面加载完成.

二、启动类型

在安卓中应用的启动方式分为以下几种:

1.冷启动

冷启动:当启动应用时,后台没有该应用的进程,系统会创建一个新的进程分配给该应用。

冷启动会先创建和初始化 Application 类,再创建和初始化 MainActivity 类,最后显示在界面上。

2 .热启动

热启动:当启动应用时,后台已有该应用的进程(如:按back键、home键)。

热启动只会创建和初始化 MainActivity 类,不会创建和初始化 Application,因为Application 只会初始化一次。

3 .首次启动

首次启动:安装应用后第一次启动的过程。

首次启动也是冷启动,比起冷启动,还会做一些系统初始化工作,如缓存目录创建、数据库创建,所以首次启动花费的时间最长。首次启动的速度非常重要,毕竟影响用户对 App 的第一映像。

三、启动流程

1.创建流程

  1. 点击应用图标后,进入Launcher的onClick(), 然后调用 startActivity (),然后调用 Instrumentation 的 execStartActivity()。
  2. Instrumentation 调用 ActivityManagerProxy (ActivityManagerService 在应用进程的一个代理对象) 的 startActivity ()。
  3. ActivityManagerProxy 跨进程调用 ActivityManagerService (运行在 system_server 进程)的 startActivity ()。
  4. ActivityManagerService 最后调用 zygoteSendArgsAndGetResult(), 通过 socket 发送给 zygote 进程,zygote 进程会孵化出新的应用进程。
  5. zygote 执行 ActivityThread 的 main()。在该方法里会先准备好 Looper 和消息队列,然后调用 attach 方法将应用进程绑定到 ActivityManagerService,然后进入 loop 循环,不断地读取消息队列里的消息,并分发消息。
  6. ActivityManagerService 保存应用进程的一个代理对象,然后 ActivityManagerService 通过代理对象通知应用进程创建入口 Activity 的实例,并执行它的生命周期函数。

2.生命周期

创建应用进程之前的流程由系统决定,没办法优化。能够优化的是Application和MainActivity 的创建和初始化。

下面是 MainActivity 的启动流程:

-> Application 构造函数
-> Application.attachBaseContext()
-> Application.onCreate()
-> Activity 构造函数
-> Activity.setTheme()
-> Activity.onCreate()
-> Activity.onStart
-> Activity.onResume
-> Activity.onAttachedToWindow
-> Activity.onWindowFocusChanged

四、启动时间

1.Activity启动时间统计

通过命令行方式统计启动时间:

adb shell am start -W appplicationId/packageName.activityName

输出的结果类似于:

$ adb shell am start -W com.speed.test/com.speed.test.HomeActivity
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.speed.test/.HomeActivity }
Status: ok
Activity: com.speed.test/.HomeActivity
ThisTime: 496
TotalTime: 496
WaitTime: 503
Complete

2.精确时间统计

通过trace文件分析每个方法的花费时间.

1.生成trace文件

  1. 使用代码生成

    先通过Debug类生成trace文件,注意加读写权限。

    Debug.startMethodTracing("shixintrace"); //开始trace,结束后会在SD卡中生成shixintrace.trace
    ... 
    Debug.stopMethodTracing(); //结束
    

    注意:在Applicaiton中开始trace,然后再MainActivity中结束trace,不会生成trace文件。

    trace文件生成后存放在SD卡中,可能直接存放/sdcard,也可能存在外置专有目录中。

    先通过以下命令找到具体路径:

    adb shell 
    cd /sdcard
    find -name *.trace
    
    可能得到如下结果
    ./Android/data/gsw.test1/files/shixintrace.trace
    

    然后退出shell状态,通过adb命令取出文件

    adb pull sdcard/Android/data/gsw.test1/files/shixintrace.trace
    
  2. 使用 Android Studio生成

    生成 trace 文件:Android Monitor -CPU监控-闹钟。

2.分析trace文件

如果使用代码生成trace文件,则需要用Android Studio打开.

分析trace文件:

  1. 先分析线程的执行时间,对时间较长的线程,再分析每个方法的执行时间和调用次数。
  2. 对于执行时间长的方法,需要分析每一步的执行时间,知道找到最深层的长耗时方法。
  3. 对于调用频繁的方法,需要逐步逐层分析调用和依赖。

五、优化方案

1.减少启动耗时

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

2.黑白屏优化

  1. 设置特定的背景

    通过设置theme的android:windowBackground属性实现。

    如果设置的背景在应用启动完成后不再需要,可以再通过setTheme()设置背景。

  2. 不显示背景

    通过设置theme的android:windowIsTranslucent属性实现:true代表透明;false代表非透明。

最后

性能优化专题:https://www.jianshu.com/nb/25128595

喜欢请点赞,谢谢!

参考链接

启动时间统计:https://www.jianshu.com/p/c967653a9468

trace文件分析 : http://www.ituring.com.cn/article/273967

启动流程分析 : http://www.jianshu.com/p/6037f6fda285

白屏产生原因 : http://blog.csdn.net/fancylovejava/article/details/39643449

上一篇 下一篇

猜你喜欢

热点阅读