我们知道App启动耗时的地方主要是在:Application初始化 和 MainActivity的界面加载绘制时间。
当MainActivity的业务和布局复杂度非常高,那么该界面必须要有一些初始化的数据才能显示。那么这个时候MainActivity就可能半天都出不来,这就给用户感觉app太卡了。我们要做的就是给用户以干净利落的体验,所触既有所得——只要用户点击app就立马弹出我们的界面。
我们常规的应用启动的时候都是这样做:
- 首先启动一个SplashActivity用于过渡, 在这上面可能会初始化一些数据资源、加载一些广告
- SplashActivity加载完成后,再跳转到MainActivity
如下图所示:
上面的做法儿有一个问题:
在SplashActivity启动之后,还是需要跳到MainActivity。MainActivity还是需要从头开始加载布局和数据。
于是我们又想到这样来优化:
SplashActivity里面可以去做一些MainActivity的数据的预加载。然后需要通过意图传到MainActivity。
可不可以再做一些更好的优化呢?耗时的问题出现在:
- Application 和 Activity的启动及资源加载时间;
- 预加载的数据花的时间。
如果我们能让这两个时间重叠在一个时间段内并发地做这两个事情就省时间了。
那可不可以这样做呢?
将SplashActivity和MainActivity合为一个。一进来还是显示的MainActivity,SplashActivity可以变成一个SplashFragment,然后放一个FrameLayout作为根布局直接显示SplashFragment界面。
SplashFragment里面非常之简单,就是现实一个图片,启动非常快。当SplashFragment显示完毕后再将它remove。同时Splash页面的2S友好时间内进行网络数据缓存。这个时候我们才看到原来需要在MainActivity上显示的View,就不必再去等待网络数据返回了。
那么问题又来了SplashView和ContentView加载放到一起来做了 ,这可能会影响应用的启动时间。毕竟在刚启动页面的时候,原来MainActivity上需要显示的View不是马上需要展示出来的。那么该怎么解决这个问题呢?
答案:ViewStub,使用ViewStub进行延迟加载。
这个时候加载流程就变成了这个样子:
下面我们看具体的代码实现:
- activity_main布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ViewStub
android:id=