概述
冷启动
热启动
App进程处于后台,系统只是将其从后台带到前台,展示给用户。屏幕会显示一个空白的窗口,直至activity渲染完毕
温启动
介于冷启动和热启动之间
用户back退出了app,然后又启动,app进程可能还在运行,但是activity需要重建
用户退出app后,系统可能由于内存原因将app杀死,进程和activity都要重启,但是可以在onCreate中将被动杀死锁保存的状态(savedInstance state)恢复
我们只需要对第一种状态做优化,优化2个环节,application.onCreate、首屏activity的渲染
子线程按优先级加载
提前加载
延后加载
启动优化方案
在启动器的概念中,我们将每一个初始化代码抽象成了一个Task,然后,对它们进行了一个排序,根据它们之间的依赖关系排了一个有向无环图,接着,使用一个异步队列进行执行,并且这个异步队列它和CPU的核心数是强烈相关的,它能够最大程度地保证我们的主线程和别的线程都能够执行我们的任务,也就是大家几乎都可以同时完成
启动优化有哪些容易忽略的注意点?
cpu time与wall time
注意延迟初始化的优化
介绍下黑科技
首先,
在CPU Profiler和Systrace中有两个很重要的指标,即cpu time与wall time,我们必须清楚cpu time与wall time之间的区别,wall time指的是代码执行的时间,而cpu time指的是代码消耗CPU的时间,锁冲突会造成两者时间差距过大。我们需要以cpu time来作为我们优化的一个方向。
其次
,我们不仅只追求启动速度上的一个提升,也需要注意延迟初始化的一个优化,对于延迟初始化,通常的做法是在界面显示之后才去进行加载,但是如果此时界面需要进行滑动等与用户交互的一系列操作,就会有很严重的卡顿现象,因此我们使用了idealHandler来实现cpu空闲时间来执行耗时任务,这极大地提升了用户的体验,避免了因启动耗时任务而导致的页面卡顿现象。
最后,
对于启动优化,还有一些黑科技,首先,就是我们采用了类预先加载的方式,我们在MultiDex.install方法之后起了一个线程,然后用Class.forName的方式来预先触发类的加载,然后当我们这个类真正被使用的时候,就不用再进行类加载的过程了。同时,我们再看Systrace图的时候,有一部分手机其实并没有给我们应用去跑满cpu,比如说它有8核,但是却只给了我们4核等这些情况,然后,有些应用对此做了一些黑科技,它会将cpu的核心数以及cpu的频率在启动的时候去进行一个暴力的提升
深入探索Android启动速度优化
https://juejin.im/post/5e6f18a951882549422ef333
创建app进程,加载相关资源,启动mainThread,初始化首屏activity
启动对统计时间点:闪屏页后的第一个Activity的onWindowFocusChanged
Application或mainactivity显示时机优化,任意门,部分耗时任务闲时加载
Sdk放子线程加载
减少xml文件inflate时间
另外还有统计函数耗时,activity调整耗时等统计
分布加载,异步加载,延期加载
IdleHandler一定会执行吗
每次消费掉一个有效message,在获取下一个message时,如果当前时刻没有需要消费的有效(需要立刻执行)的message,那么会执行IdleHandler一次,执行完成之后线程进入休眠状态,直到被唤醒
自定义view、反复requestLayout、第三方库有的用Handler、AsyncTask 来发大量消息的时候,就会出现 idle 始终不执行,排查起来比较麻烦
注释中明确的指出当消息队列空闲时会执行IdelHandler的queueIdle()方法,该方法返回一个boolean值,
如果为false则执行完毕之后移除这条消息,
如果为true则保留,等到下次空闲时会再次执行
启动优化
1、闪屏页
2、异步加载/线程池,设置优先级,排序
3、延迟加载
4、主页UI层级优化
出现白屏原因:
系统加载布局文件是需要时间的,在刚启动时布局文件还没加载完毕(即setContentView(int)之前)显示的是window背景,出现的白屏(或黑屏)是window的背景色
App启动优化
回答:打点计时;任务看做Task放优先级线程池,异步有序执行,延后执行
1、启动打点,计时
AppMainApplication&attachBaseContext
AppMainApplication&onCreate
SplashActivity.onResume
MainActivity.onResume
2、优化方案
关于启动优化的问题,如果只是很表面地回答耗时操作应该放在子线程,显然太过于普通,无法跟竞争者拉开差距。如何让面试官知道你的“内功深厚”,那肯定是要往原理层面去回答
冷启动优化这个问题能延伸到很多原理层面的知识点?
一、应用启动流程
应用进程不存在的情况下,从点击桌面应用图标,到应用启动(冷启动),大概会经历以下流程:
- Launcher startActivity
- AMS startActivity
- Zygote fork 进程
- ActivityThread main()
- 4.1. ActivityThread attach
- 4.2. handleBindApplication
- 4.3 attachBaseContext
- 4.4. installContentProviders
- 4.5. Application onCreate
- ActivityThread 进入loop循环
- **Activity****生命周期回调,onCreate、onStart、**onResume…
整个启动流程我们能干预的主要是 4.3、4.5 和6,应用启动优化主要从这三个地方入手。理想状况下,这三个地方如果不做任何耗时操作,那么应用启动速度就是最快的,但是现实很骨感,很多开源库接入第一步一般都是在Application onCreate方法初始化,有的甚至直接内置ContentProvider,直接在ContentProvider中初始化框架,不给你优化的机会
二、启动优化
直奔主题,常见的启动优化方式大概有这些:
-
闪屏页优化-消除启动时的白屏/黑屏
-
MultipDex优化(本文重点)
-
说 MultiDex之前,先梳理下apk编译流程
-
2.2.1 apk编译流程
-
Android Studio 按下编译按钮后发生了什么?
-
打包资源文件,生成R.java文件(使用工具AAPT)
-
处理AIDL文件,生成java代码(没有AIDL则忽略)
-
编译 java 文件,生成对应.class文件(java compiler)
-
.class 文件转换成dex文件(dex)
-
打包成没有签名的apk(使用工具apkbuilder)
-
使用签名工具给apk签名(使用工具Jarsigner)
-
对签名后的.apk文件进行对齐处理,不进行对齐处理不能发布到Google Market(使用工具zipalign)
-
在Android 4.4的机器打印 MultiDex.install**(context)**耗时如下:1320ms
-
https://blog.csdn.net/androidstarjack/article/details/103143119
-
Tinker****热修复的原理也是通过反射将修复后的dex添加到这个dex数组去
-
第三方库懒加载
-
WebView优化
-
线程优化
-
系统调用优化
最后
以上就是斯文小天鹅为你收集整理的启动优化的全部内容,希望文章能够帮你解决启动优化所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复