子曰:温故而知新,可以为师矣。 《论语》-- 孔子
作为性能优化专栏的第二篇,阅读本文章前可以先阅读 (一)Android 黑白屏由来以及解决方案,再阅读本篇文章效果更佳。
一个完美的 App 启动,无疑会给第一次使用该应用的用户一个良好的体验。
在构建 App 时,我们经常需要引用一些第三方的 sdk,而随着项目业务增多,引用的第三方库也越多,有些第三方要求我们在 Application 的 onCreate() 方法中对其初始化。这意味着: 在 Application
的 onCreate()
方法中执行的时间 越长
,首个 Activity 布局渲染时间也会相应的拉长。
同理,如果我们在 Activity 的 onCreate(),onStart(),onResume() 方法中执行的任务时间过长
,同样也会导致布局渲染的时间拉长。这样直接导致的问题就是,用户会感觉页面迟迟没有加载出来,用户体验感极差,到时候产品或者运营可能就提着三米大刀杀过来了,哈哈,开个玩笑。
作为一个合格的开发者,我们知道 App 被系统调用,再到第一个页面渲染到手机屏幕。我们通常只需要关注 Apolication 中的 onCreate() 方法
,第一个 Activity 中的onCreate() ,onStart() ,onResume() 方法
。需要注意的是:如果在 App 启动第一个 Activity 时,该 Activity 不但有自己的逻辑,还在 onCreate(),onStart()或者 onResume() 方法中直接又跳转到了其他 Activity 页面,那么跳转后的 Activity 的这三个方法也需要进行优化
。
好了,罗里吧嗦地说了一堆,那么大家最关心的就是如何去优化,不要着急哦,下面来具体的说一些解决方案,保证是诚意满满的干货。
1. App 启动时间检测
Android Studio 终端中输入以下命令:
adb shell am start -W [项目包名]/[要启动的Activity的名字]
例如:
adb shell am start -W com.imooc.imooc_voice/com.imooc.imooc_voice.view.loading.LoadingActivity
我这边启动的是 LoadingActivity ,也就是 SplashActivity,可以在终端看到有三个 time:
This Time
:最后一个 Activity 启动时间。
Total Time
:一系列 Activity 启动时间。
Wait Time
:总启动时间,包含系统在冷启动时,需要加载 app 信息到内存中。
在这其中,我们能够优化的是 Total Time
这一个部分,前提是你应用启动的时间你觉得过长。那么我们怎么知道到底是哪块代码,或者说是哪个三方的 sdk 初始化的时候加载时间过长,那么就需要知道 代码执行时间统计的方法
。
2. 代码执行时间统计方法
1.我们在自己的 Application 文件中 加入以下代码,这是我自己项目中的 Application 文件
:
public class ImoocVoiceApplication extends Application {
private static ImoocVoiceApplication mApplication = null;
@Override
public void onCreate() {
super.onCreate();
File file = new File(Environment.getExternalStorageDirectory(),"app.trace");
Debug.startMethodTracing(file.getAbsolutePath());
mApplication = this;
//视频SDK初始化
VideoHelper.init(this);
//音频SDK初始化
AudioHelper.init(this);
//分享SDK初始化
ShareManager.initSDK(this);
//更新组件下载
UpdateHelper.init(this);
//ARouter初始化
ARouter.init(this);
Debug.startMethodTracing();
}
public static ImoocVoiceApplication getInstance() {
return mApplication;
}
}
2.我们通过命令获取 trace 文件
:
adb pull /storage/emulated/0/app.trace
3.将 trace 文件 直接拖到 Android Studio 中,如下图所示
:
从这张图下面可以看出,我自己的项目耗时比较长的就是这个 ARouter
初始化以及 ShareSDK
的初始化,我这边选择的是 Top Down
模块下查看,我认为这个最方便,大家也可以点击其余模块查看,这个看个人习惯。
既然知道了问题,那么该怎么优化呢,这边给出 2 个方案:
1. 这边的初始化都是在主线程进行的,可以用异步线程方式处理。
- 注意:如果你把某些初始化操作放在了异步线程中,那么初始化的代码中
不能有创建 Handler 的操作
,不能有 UI 操作
,同时此方式仅限于对异步要求不高
,即在异步方式下你优化的初始化操作时间不能过长,这是为了防止万一你首页界面的数据可能需要等到Appliction
界面中的初始化操作完成后才能获取到,而你将部分初始化操作放在了异步线程中,这样可能导致数据获取不到。
2. 懒加载。
- 有的开发者喜欢在
Application
中初始化OKHttp
,这是比较耗时的,那么就可以用懒加载去解决,即用到了再去初始化OKHttp
。
这边我就提供这两种思路,至于具体的详细优化操作还是要根据各位自己项目的实际应用以及需求来优化。当然,如果你有更好的优化思路,欢迎讨论,大家一起共同进步,一同成长。
写在文末
纸上得来终觉浅,绝知此事要躬行。 《冬夜读书示子聿》-- 陆游
关于 App启动时间优化 之 代码实现的方案就说到这了,大家可以根据文章中给出的方案,结合自己的项目去优化。