APP启动优化

[TOC]

APP启动优化

启动方式

冷启动

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

application以及activity初始化是一个比较复杂的过程,而白屏或黑屏就是这个过程的产物。

在应用程序刚启动到应用程序初始化完全之间有一段时间空隙,这时候系统创建了一个空白窗口,叫StartingWindow。这个窗口是一个临时窗口,对应的WindowType是TYPE_APPLICATION_STARTING。应用程序加载完第一帧后,这个窗口就会被移除。

Window的顶层是DecorView,所以StartingWindow显示一个空DecorView,但是会给这个DecorView应用当前Activity指定的Theme,如果这个activity没有指定Theme就用application的,如果Theme是白色的,屏幕就是白色的;如果是Dark,就会显示黑屏。

热启动

后台已有该应用的进程(按back键、home键)

热启动在直到应用完成渲染之前都会一直显示一个空白窗口。

App启动过程

ActivityThread运行在应用进程的主线程上,响应AMS启动、暂停Activity,广播启动等消息。

AMS:统一调度各应用程序的Activity、内存管理、进程管理

  1. 点击Launcher,启动程序,通知ActivityManagerService
  2. AMS通知zygote进程孵化出应用进程,分配内存空间等
  3. 执行该应用ActivityThread的main方法
  4. APP通知AMS,AMS保存一个该应用的代理对象,AMS通过它可以控制应用进程
  5. AMS通知应用进程创建入口的Activity实例,执行它的生命周期
    • Application的构造方法
    • attachBaseContext()
    • onCreate()
    • LauncherActivity的构造方法
    • setTheme()设置主题等信息
    • Activity的生命周期

启动页优化

设置一个启动页SplashFragment进行过度。并在MainActivity中优先展示SplashFragment,显示完毕后再进行remove。当然MainActivity的主布局可以采用ViewStub进行懒加载。

1
2
3
4
5
6
7
8
9
10
11
protected void onCreate(Bundle savedInstanceState){
setContentView();
//显示splashFragment

getWindow().getDecorView().post(new Runnable(){
//渲染主界面,用队列
viewStub.inflate();
});

//等时间结束后,取消splashFragment,呈现主界面
}

评估

  1. 系统提供的启动时间方案

    logcat的输出,关键字为Displayed

  2. ADB命令提供的启动时间方案

    1
    adb shell am start -w packagename/activity

    ThisTime:一连串启动的activity中的最后一个activity的启动耗时
    TotalTime:新进程的Activity的启动耗时,但不包括前一个应用activity中pause()方法的耗时
    WaitTime:总的耗时

    一般情况下ThisTime和TotalTime耗时是相同的。有一个场景会导致这两个值不同,比如点击App图标,先启动一个无界面的activity做逻辑处理,接着又启动一个有界面的activity

  3. 利用TraceView进行分析

    • 使用方法
      • AS中的startMethodTracing
      • 代码中使用Debug.startMethodTracing(“xxx.trace”)和stop,然后sdcard下会生成trace文件
    • 最关心的数据
      • Calls+Recur Calls / Total, 查找自身占用时间不长,但是调用频繁的操作
      • Cpu Time / Call , 某个函数消耗CPU的平均时间,一般用来查找调用次数不多,但每次调用却需要花费很长时间的方法

界面优化

  1. 尽量使用include、merge、ViewStub标签
  2. 不使用冗余嵌套和过于复杂布局
  3. 尽量使用GONE替换INVISIBLE
  4. 使用weight后尽量将width和height设置为0
  5. item存在复杂嵌套关系时用自定义View替代,减少measure与layout次数
  6. 主题上使用windowbackground为启动Activty设置简单的自定义Drawable
  7. 第三方SDK在使用到的地方再进行初始化
0%