美文网首页
性能优化 - 启动时间

性能优化 - 启动时间

作者: 慎独静思 | 来源:发表于2022-04-19 06:44 被阅读0次

    应用的启动分为:冷启动,暖启动和热启动。其中冷启动是我们优化的重点,优化冷启动可能会同时优化暖启动和热启动。

    冷启动

    是指开机后第一次启动或应用被杀后启动,在启动之前应用的进程不存在。
    冷启动过程中系统会:
    1、加载和启动应用;
    2、启动之后立即展示黑屏的启动窗口;
    3、创建应用进程。
    一旦应用进程创建,则由进程负责后续的操作。
    1、创建app对象;
    2、启动主线程;
    3、创建main Activity;
    4、加载布局;
    5、在屏幕上布局;
    6、执行首次绘制;
    首次绘制以后会去掉黑屏窗口,显示Main Activity的内容。

    应用启动.png

    我们的优化主要集中在APP和Activity的创建过程中。

    暖启动

    是介于冷启动和热启动之间的一种启动形式,比如:
    1、用户退出了应用之后重新启动,进程虽然存在,但是Activity需要重建,重新回调onCreate.
    2、进程和Activity都需要重建的情况,但仍然比冷启动的工作要少。

    热启动

    是系统把你的Activity带到前台的过程。
    热启动时系统同样会先显示黑屏的窗口。


    启动类型.png

    Displayed Log

    ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms
    

    咱们可以在应用启动log中查看带Displayed的Log,查看启动的时间。
    这个时间包含:启动进程,创建对象,创建初始化Activity,加载布局,首次绘制。

    ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms (total +1m22s643ms)
    

    有时候log中会包含一个总时间,这说明Activity的启动时间和应用总启动时间不同,第一个时间就代表Activity的启动时间。

    adb [-d|-e|-s <serialNumber>] shell am start -S -W
    com.example.app/.MainActivity
    -c android.intent.category.LAUNCHER
    -a android.intent.action.MAIN
    

    其中: -W: Wait for launch to complete.
    -S: Force stop the target app before starting the activity.

    通过以上命令,咱们可以统计应用启动时间

    MacBook-Pro:workspace kkl$ adb shell am start -S -W com.lkk.eventconflictdemo/.MainActivity
    Stopping: com.lkk.eventconflictdemo
    Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.lkk.eventconflictdemo/.MainActivity }
    Status: ok
    LaunchState: COLD
    Activity: com.lkk.eventconflictdemo/.MainActivity
    TotalTime: 558
    WaitTime: 559
    Complete
    
    MacBook-Pro:workspace kkl$ adb shell am start -W com.lkk.eventconflictdemo/.MainActivity
    Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.lkk.eventconflictdemo/.MainActivity }
    Status: ok
    LaunchState: WARM
    Activity: com.lkk.eventconflictdemo/.MainActivity
    TotalTime: 328
    WaitTime: 329
    Complete
    
    MacBook-Pro:workspace kkl$ adb shell am start -W com.lkk.eventconflictdemo/.MainActivity
    Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.lkk.eventconflictdemo/.MainActivity }
    Warning: Activity not started, its current task has been brought to the front
    Status: ok
    LaunchState: HOT
    Activity: com.lkk.eventconflictdemo/.MainActivity
    TotalTime: 122
    WaitTime: 134
    Complete
    

    我测试用的就是一个简单的单Activity的demo。
    从输出结果我们可以看到三种不同的LaunchState:COLD,WARM,HOT。
    第一次启动时我添加了-S,会在启动之前杀掉应用,第二,三次我去调了-S。
    第二次我点击了返回键,第三次我点击了home键。

    reportFullyDrawn()

    我们可以手动调用Activity提供的方法reportFullyDrawn()来记录启动时间,输出如下。

    system_process I/ActivityTaskManager: Fully drawn com.lkk.eventconflictdemo/.MainActivity: +115ms
    

    怎么定位启动时间问题

    咱们可以优化的点主要集中在Application和Activity的create方法中。
    Application#onCreate中的耗时操作主要是,全局对象的初始化等。
    Activity#onCreate中的耗时操作主要是,复杂布局文件的加载,一些不必要的初始化,耗时操作等。
    当然除了这些方法,肯定有很多好用的工具帮助我们定位问题,比如MatrixDoraemonKitbooster
    等。

    怎么解决启动时间问题

    Application中耗时的解决办法主要是,延迟初始化。对于一些耗时全局对象的创建,可以延迟到真正需要它的时候。
    如果你使用content provider初始化组件,可以考虑使用App Startup 替代。

    咱们可以考虑布局优化中的方法优化复杂的布局。
    可以考虑把一些操作放在子线程中处理。
    可以考虑采用懒加载的方式处理一些页面的加载。

    以上都是基本的优化方法,我们还可以考虑其他的方式,比如:
    1、systrace + 字节码插桩
    2、通过 redex 重排列 class 文件

    这里只是罗列出来,后边详细学习,并贴学习总结链接。

    参考:
    1、App startup time
    2、Android App 启动优化全记录
    3、深入探索Android启动速度优化
    4、都9102年了,Android 冷启动优化除了老三样还有哪些新招?
    5、Android性能优化笔记(一)——启动优化

    相关文章

      网友评论

          本文标题:性能优化 - 启动时间

          本文链接:https://www.haomeiwen.com/subject/drazsrtx.html