项目优化实战 —— App启动时间优化

2019-02-19  本文已影响8人  设计失

一顿骚操作写完项目之后,运行一看炸裂了;在冷启动的时候,APP启动时间居然要十几秒,当遇到白屏或者黑屏的时候,更多的是想到了使用background的方式来替换刚刚启动时候的界面显示,但是这样通常是治标不治本的;因为使用background的方式应用的启动时间是不变的,导致用户停留在闪屏页面时间过长,接下来我们来分析一下应用启动耗时

看完本篇文章你将了解到:
· 在`logcat`中查看界面启动时间
· 使用`adb`方式启动`Activity`查看耗时时间
· 使用`Debug`来追踪方法中函数耗时
· 使用`Android Studio`来查看`trace`文件,分析`trace`文件中耗时方法
· 优化应用启动时间

在logcat中查看应用启动时间

使用真机调试的时候,往往因为logcat打印太快而忽略了系统打印的一些信息,比如displayed 是用来记录Activity的启动时间:

在logcat中查看.png

注意 画框 的地方: 选中自己调试的应用,在过滤输入框中输入 displayed 启动自己的调试的应用之后,将会看到如图中显示的打印时间; 可以看到,当前应用启动时间是非常久的,我使用该应用之后的第一个想法是卸载(摊手)

使用logcat查看可能觉得太low,不能展示我们装逼的格调,接下来我们使用adb的方式启动应用:

使用adb shell命令的方式启动Activity查看启动时间

adbsdk platform-tools 中的一个工具,我们先将其添加到环境变量中,然后在终端调用adb ,可以看到一系列的命令; 我们这里不作命令的讲解,既然是要查看Activity启动时间,而Activity的启动都是由ActivityManager am 管理; 当我们在官网查看adb命令时,下面则对am进行了讲解:
https://developer.android.com/studio/command-line/adb?hl=zh-cn#shellcommands

接下来我们使用 adb shell am的方式启动Activity:

优化前使用adb shell 查看启动时间.png

可以看到总的启动时间为 3096 毫秒 , 在logcat中最后一次的SplashActivity启动时间一样;上面使用了两种方法来查看应用启动到第一个界面的等待总时间,可以看到当点击应用图标时进入到页面花费了大量的时间,那这个时间做什么去了呢?

分析Application中 onCreate 耗时

点击应用图标启动到进入界面的这段逻辑中,系统做了大量的初始化操作,而这些操作我们是无法进行优化的,所以只能在onCreate()方法中进行优化处理;

官网中对日志追踪有详细的介绍,这里不再赘述;我们直接使用
官网介绍:https://developer.android.com/studio/profile/generate-trace-logs?hl=zh-cn#instrument

假设在这里你已经看懂了使用Debug来追踪调试日志的方法,我们使用Debug.startMethodTracing(file.getAbsolutePath()); 来告诉系统开始追踪方法,使用 Debug.stopMethodTracing() 停止追踪,两个方法之间就是你需要追踪调用时间的代码;

具体使用 :

@Override
public void onCreate() {
    super.onCreate();

    File file = new File(Environment.getExternalStorageDirectory(), "app");
    Log.d("Debug ====", file.getAbsolutePath());
    Debug.startMethodTracing(file.getAbsolutePath());
    dbApplication = this;

    // .... 省略实际代码

    Debug.stopMethodTracing();
}

当然作为调试,这里没有做权限申请,你需要在应用启动之前设置允许该应用的存储权限;加入该代码之后,重新运行一次,你将在/storage/emulated/0 目录下看到 app.trace文件,使用adb pull 命令将该文件导出:

导出trace追踪文件.png

接着将该文件拖动到android studio中,接下来你将看到最新的Android studio 分析 trace文件:

android studio查看trace文件.png

和之前的版本不同的是,最新版本的分析可以清楚的看到哪些调用耗时时间;在分析出的结果中,我们看到项目中使用的Mob分享和小米推送两个耗时最多,接下来我们将一个个优化,既然是第三方的sdk,最先考虑的是能不能将其放入到子线程中和启动页面中,这样既避免了启动耗时,同样也不会影响后面的操作流程; 当然,有些第三方sdk需要使用到Handler, 这样我们另做考虑; 接下来我们将优化其中的耗时调用,

优化第三方SDK

我将MobSDK.init放入到闪屏页面中的子线程中

// 使用Rxjava
Observable.just("").subscribeOn(Schedulers.io()).subscribe(s -> getModel().MobSDKInit());

一开始,我们是不知道第三方sdk是否能放入到子线程中的,所以,我们只能试探性的运行尝试,不行再尝试其他方法;修改完代码之后,我们再次Debug调试,重复Debug ApplicationonCreate() 方法, 调出trace文件查看结果:

去掉Mob sdk之后.png

调试之后,看到运行时间轴消耗时间,别吓到了,每次显示的是占用时间最长的,这里我们使用同样的方式优化接下来的第三方sdk;

我们将小米推送放入到闪屏的子线程中,看到trace文件中没有了耗时,而且要用正常执行,没有报错:


优化小米推送之后.png

接下来,我们看到一长条的FeedbackApi 这是阿里的反馈初始化,优化它

优化阿里反馈.png

按照如上的操作,我相信同学们应该都会优化了;将所有的优化进行完之后,我们看下启动时间:


最后启动时间.png

上面详细讲解了从启动时间的获取到第三方sdk的优化,当然我这里都是在子线程执行,因为大部分第三方的sdk不涉及到Handler的使用,但是不可避免的是会遇到;下面就有这种情况,当使用腾讯的IM的时候,使用到了Handler,所以在这里建议使用IntentService,关于IntentService使用,大家自行谷歌吧~

总结

到最后, 应该都懂得了启动优化,不再简单的使用background的方式来填充了,应该找到根本原因~

优化主要分为:

  • Debug.startMethodTrace 开始Trace
    Debug.stopMethodTrace 结束Trace
  • 获取到trace文件
  • 分析方法中耗时调用
  • 优化
上一篇下一篇

猜你喜欢

热点阅读