近日在开发过程中,发现每次点击app从桌面启动都有一个在桌面明显的等待时间,机型越低端的越明显,冷启动优化看来已经势在必行。

1.冷启动相关优化点:

生命周期内减少耗时操作

Application:attachBaseContext():

这个方法中一般雷区主要都在这句代码上,因为在Android 5.0(API 21) 以下会存在65535方法数分包的问题,当dex过大时会导致Application启动慢, ANR或者ClassNotFound等异常,关于分包解决和优化方案网上一堆就不在做赘述了。

Application:onCreate()

这个方法是需要重点优化的,因为大家的第三方插件初始化一般都会放在这里,在Application初始化做繁重的东西会严重阻塞app启动(DiskIO,网络请求等)。以下是我们第三方插件初始化的耗时:
针对于解决第三方插件初始化耗时方案一般是:
1.SDK分优先级加载,非必要SDK由懒加载实现。
2.可以多线程初始化的sdk由多线程方式来进行初始化。
MainActiviity:onCreate()
同上一样,尽量不要在此布局做一些耗时的操作或者呈现一些过于复杂的布局。在具体分析自己的app时发现onCreate中有这样一行代码:
其作用是希望用户在打开时,一定能看见Splash的画面,主动延迟了1s加载。这里其实有更好的解决办法处理,则是把跳转MainPage的方法放在onResume中而不是放在onCreate中。因为Android系统中onResume一定是处于可见可交互的状态,用户一定能看见SplashActivity再去跳转,由系统生命周期决定,而不是固定的等待1s,此处优化后启动速度又提升了500ms。所以建议大家以后还是遵循生命周期去做一些事情,尽量别进行人为延迟阻塞。

2. 避免冷启动

App启动方式一般有3种:

  • ColdStart ——冷启动:

此种方式最为耗时,一般是因为进程被干掉,系统需要重新fork进程进行一系列初始化。

  • WarmStart ——暖启动

比ColdStart稍快,因为app的所有Activities还常驻在内存中,并没有被杀掉,所做的只是把app从后台提到前台来展示,并不需要重走初始化一系列行为,减少了对象初始化、布局加载等工作。但其行为表现与冷启动一致,是会displays a blank screen直到App渲染activity。这个blank screen后面会解释。

  • LukeWarm Start——热启动

启动方式最快,类似于返回键退出应用又立即进入的那种行为。
优化方案:
既然冷启动那么慢,我们就在非用户主动kill进程或系统通知kill进程的其他情况下不再主动退出进程。那答案很简单了,就是在位于Activity栈底activity中Hook其返回键行为,保证用户点击返回键后不再退出app。在我们App里位于我们栈底的一定是我们的MainActivity,因为一系统行为都是由其向下衍生的。所以只需在onBackPressed()方法中加入以下几句话:moveTaskToBack(true);
moveTaskToBack:作用是不再Finish到此Activity,仅仅是把它放到后台隐藏。类似于用户主动触发系统Home键的效果。

3.WindowBackGround——脱下秒开的最后一层薄丝袜

经过上面一顿操作后,我发现然并卵!!!启动速度是提升了,但是App一点击还是会在桌面停顿一下。哇呀~很难受~细细思考了一下,一个APP启动无论如何都是会新Fork进程,难道就是这个问题导致其在桌面上停顿一会儿?那其他app又是怎么做到秒开的呢?在AndroidDeveloper的Launch-Time Performance有这么一句话:

其实在创建App进程时,android系统会为你立即显示一个background window,然后再去创建app进程,当app完成first draw时,会立即由你的MainActivity(即默认启动的Activity)替换掉它。这里的background window就是上文WarmStart中提到的blank screen。谜底到此解开所谓的秒开原来就是视觉欺骗。。。所以说有人给你说他只是仅仅是优化生命周期内初始化代码达到秒开都是扯淡。但不得不承认这样用户体验大大的提升了,一点击launcher就渲染好一个背景图片,给用户一种已经启动的感觉,前面做的一系列优化,不过为了让用户少看一会儿系统给渲染的black window。

那为什么我们的APP会出现在系统桌面上停留一会,而不是渲染背景图呢?原来在项目创建时,系统会为launcherActivity默认了一个LightTheme,这样就会导致App点击启动后会白屏一段时间然后展示自己的Activity,为了解决白屏的问题把theme主题换成透明的就像下面

但其实这样虽然解决了白屏的问题,但是就会出现上文所说的,点击后停留在桌面一会儿,直至MainActivity渲染出来。这是大部分App的做法,但并不是最佳解决方案。

WindowBackground最佳解决方案:

应该由windowBackground此属性作为你的品牌推广页或者logo页,如果你的SplashActivity完全不需要做任何初始化,只是希望有个闪屏页,完全可以由windowBackground来满足。

a.设置自定义带windowBackground的Theme


前两行代码是设置Theme不透明并且默认渲染的背景图是我们必看影视闪屏页的图片。

windowBackground:关键,主要设置你想要的背景图或者是动态自绘的drawable皆行,这个视图会在你冷启动时渲染给用户过渡看。

windowFullscreen:全屏展示,免得顶部状态栏显现颜色不一致过于脱节和突兀

b. 为你的launcher Activity设置你的启动Theme

c.在Launch Activity启动后再把主题设置回自己的AppTheme


此时你的App就能完成秒开了!

4.如果用到SharePreference,尽量在异步线程中操作

5.减少布局的层次,并且生命周期回调的方法中尽量减少耗时的操作

参考资料:https://mp.weixin.qq.com/s/a8076txSPIUqGAbe30uEug
http://www.jb51.net/article/93502.htm

更多相关文章

  1. Android 事件输入系统整体框架
  2. Android 启动系统相机,相册,裁剪图片及6.0权限管理
  3. Android群英传笔记—第1章 Android体系与系统架构
  4. javaweb--Tomcat>>基于windows 系统源码的编译和部署
  5. JAVA WEB 中添加中科院分词系统ICTCLAS
  6. Android - 在一个应用程序中启动另外一个已经安装的应用程序或系
  7. 使用 VirtualBox 虚拟机在电脑上运行 Android 4.0 系统,让电脑瞬
  8. 实现Linux/Android双系统启动和重启切换的一个思路
  9. android技巧:把自己的app变成手机系统自带的app[/system/app]

随机推荐

  1. Android生成和扫描二维码之ZXing
  2. 【Android】自定义控件之View原理与使用
  3. Android面试简录——组件
  4. Android系统架构概况
  5. repost:Android shell 下 busybox,clear,tc
  6. 收集的android开源项目,android学习必备
  7. Android的JNI用法
  8. android 2048游戏实现
  9. Android类装载机制
  10. 如果让我重新设计一款Android App