解决在桌面上点击APP图标后经过一两秒后才显示页面,以及App启动后主界面显示过慢问题
一、应用的启动方式
1、冷启动:当启动应用时,后台没有该应用的进程,这时系统会首先会创建一个新的进程分配给该应用,这种启动方式就是冷启动。
2、热启动:当启动应用时,后台已有该应用的进程,比如按下home键,这种在已有进程的情况下,这种启动会从已有的进程中来启动应用,这种启动方式叫热启动。
3、温启动 :当启动应用时,后台已有该应用的进程,但是启动的入口Activity被干掉了,比如按了back键,应用虽然退出了,但是该应用的进程是依然会保留在后台,这种启动方式叫温启动。
二、应用的启动时间统计
adb shell am start -W -S -R 10 [PackageName]/[PackageName.MainActivity]
查看当前正在应用包名和当前Activity名称命令:
adb shell dumpsys activity activities |grep "mActivityComponent"
其中-S表示每次启动前先强行停止,-R表示重复测试次数。每一次的输出如下所示信息。
例如下图:
执行成功后将返回三个测量到的时间:
(1)ThisTime:指当前指定的MainActivity启动时间 ,一般和TotalTime时间一样,除非在应用启动时开了一个透明的Activity预先处理一些事再显示出主Activity,这样将比TotalTime小
(2)TotalTime:整个应用的启动时间,Application+Activity的使用的时间。
(3)WaitTime:一般比TotalTime大点,包括系统影响的耗时
三、应用启动流程
启动虚拟机—>启动AMS —>通过Zygote创建ApplicationProcess进程–>Application的构造器方法——>attachBaseContext()——>onCreate()——>Activity的构造方法——>onCreate()——>配置主题中背景等属性——>onStart()——>onResume()——>测量布局绘制显示在界面上。
因为上面这些阶段全部都是在主线程中执行的,任何不经意的操作都可能拖慢应用的启动速度。所以我们不应在Application以及Activity的生命周期回调中做任何费时操作,具体指标大概是你在onCreate,onResume,onStart等回调中所花费的总时间最好不要超过400ms,否则用户在桌面点击你的应用图标后,将感觉到明显的卡顿。但是有些不得以的任务又必须在UI显示之前执行。所以我们要将任务划分优先级。
- 优先级为1的在应用启动时,开始加载
- 优先级为2的在首页渲染完成后,开始加载
- 优先级为3的在首页渲染完成后,延迟加载
对于首页渲染完成后,开始加载,或者延迟加载,延迟加载的目的就是界面先显示出来,然后加载,但是你觉得要延迟多久呢?在 Android 的高端机型上,应用的启动是非常快的 , 这时候只需要 Delay 很短的时间就可以了, 但是在低端机型上,应用的启动就没有那么快了,而且现在应用为了兼容旧的机型,往往需要 Delay 较长的时间,这样带来体验上的差异是很明显的。延迟加载有一种方式。
第一种写法:直接PostDelay 300ms. myHandler.postDelayed(mLoadingRunnable, DEALY_TIME);
第二种写法:优化的DelayLoad getWindow().getDecorView().post(new Runnable() { @Override public void run() { myHandler.post(mLoadingRunnable); } });
三、解决方案
-
Application处理
使用启动服务执行耗时操作
- Avtivity处理
SplashActivity改成SplashFragment,应用程序的入口仍然是MainActivity,在MainActivity中先展示SplashFragment,当SplashFragment显示完毕后再将它remove,
同时在SplashFragment的2S的友好时间内进行网络数据缓存,在窗口加载完毕后,我们加载activity_main的布局,考虑到这个布局有可能比较复杂,耽误View的解析时间,
采用ViewStub的形式进行懒加载。这样一开始只要加载SplashFragment所展示的布局就Ok了。
四、参考代码及实现
具体实现可参考: