Android优化应用启动速度
一、应用的启动
启动方式
通常来说,在安卓中应用的启动方式分为两种:冷启动和热启动。
- 1、冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,这个启动方式就是冷启动。
- 2、热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动应用,这个方式叫热启动。
特点
1、冷启动:冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类,再创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。
2、热启动:热启动因为会从已有的进程中来启动,所以热启动就不会走Application这步了,而是直接走MainActivity(包括一系 列的测量、布局、绘制),所以热启动的过程只需要创建和初始化一个MainActivity就行了,而不必创建和初始化Application,因为一个 应用从新进程的创建到进程的销毁,Application只会初始化一次。
上面说的启动是点击app的启动图标来启动的,而另外一种方式是进入最近使用的列表界面来启动应用,这种不应该叫启动,应该叫恢复。
二、应用启动的流程
在安卓系统上,应用在没有进程的情况下,应用的启动都是这样一个流程:当点击app的启动图标时,安卓系统会从Zygote进程中fork创建出一 个新的进程分配给该应用,之后会依次创建和初始化Application类、创建MainActivity类、加载主题样式Theme中的 windowBackground等属性设置给MainActivity以及配置Activity层级上的一些属性、再inflate布局、当 onCreate/onStart/onResume方法都走完了后最后才进行contentView的measure/layout/draw显示在界 面上,所以直到这里,应用的第一次启动才算完成,这时候我们看到的界面也就是所说的第一帧。
所以,总结一下,应用的启动流程如下:
Application的构造器方法—— >attachBaseContext()——>onCreate()——>Activity的构造方法—— >onCreate()——>配置主题中背景等属性——>onStart()——>onResume()——>测量布局绘 制显示在界面上。
三、测量应用启动的时间
在上面这个启动流程中,任何一个地方有耗时操作都会拖慢我们应用的启动速度,而应用启动时间是用毫秒度量的,对于毫秒级别的快慢度量我们还是需要去精确的测量到到底应用启动花了多少时间,而根据这个时间来做衡量。
什么才是应用的启动时间
从点击应用的启动图标开始创建出一个新的进程直到我们看到了界面的第一帧,这段时间就是应用的启动时间。
我们要测量的也就是这段时间,测量这段时间可以通过adb shell命令的方式进行测量,这种方法测量的最为精确,命令为:
1
|
adb shell am start -W [packageName]/[packageName.MainActivity] |
执行成功后将返回三个测量到的时间:
1、ThisTime:一般和TotalTime时间一样,除非在应用启动时开了一个透明的Activity预先处理一些事再显示出主Activity,这样将比TotalTime小。
2、TotalTime:应用的启动时间,包括创建进程+Application初始化+Activity初始化到界面显示。
3、WaitTime:一般比TotalTime大点,包括系统影响的耗时。
下面是测量一个应用冷启动和热启动的时间:
冷启动:
热启动:
可以看到在进程已经存在的情况下,只需要重新初始化MainActivity,这样的启动比较快,不过大多数情况下应用的启动都是冷启动,因为用户都会在任务列表中手动关闭遗留的应用进程。
四、减少应用启动时的耗时
针对冷启动时候的一些耗时,如上测得这个应用算是中型的app,在冷启动的时候耗时已经快700ms了,如果项目再大点在Application中配置了更多的初始化操作,这样将可能达到1s,这样每次启动都明显感觉延迟,所以在进行应用初始化的时候采取以下策略:
- 1、在Application的构造器方法、attachBaseContext()、onCreate()方法中不要进行耗时操作的初始化,一些数据预取放在异步线程中,可以采取Callable实现。
- 2、对于sp的初始化,因为sp的特性在初始化时候会对数据全部读出来存在内存中,所以这个初始化放在主线程中不合适,反而会延迟应用的启动速度,对于这个还是需要放在异步线程中处理。
- 3、对于MainActivity,由于在获取到第一帧前,需要对contentView进行测量布局绘制操作,尽量减少布局的层次,考虑StubView的延迟加载策略,当然在onCreate、onStart、onResume方法中避免做耗时操作。
遵循上面三种策略可明显提高app启动速度。
优化应用启动时的体验
对于应用的启动时间,只能是尽量的避免一些耗时的、非必要的操作在主线程中,这样相对可以缩减一部分启动的耗时,另外一方面在等待第一帧显示的时间
里,可以加入一些配置以增加体验,比如加入Activity的background,这个背景会在显示第一帧前提前显示在界面上。
1、先为主界面单独写一个主题style,设置一张待显示的图片,这里我设置了一个颜色,然后在manifest中设置给MainActivity:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<style name= "AppTheme.Launcher" > <item name= "android:windowBackground" > @drawable /bule</item> </style> //... <activity android:name= ".MainActivity" android:label= "@string/app_name" android:theme= "@style/AppTheme.Launcher" > <intent-filter> <action android:name= "android.intent.action.MAIN" /> <category android:name= "android.intent.category.LAUNCHER" /> </intent-filter> </activity> |
2、然后在MainActivity中加载布局前把AppTheme重新设置给MainActivity:
1
2
3
4
5
6
7
|
@Override protected void onCreate(Bundle savedInstanceState) { setTheme(R.style.AppTheme); super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); } |
这样在启动时会先显示background,然后待界面绘制完成再显示主界面。
Android优化应用启动速度的更多相关文章
- Android性能优化之启动速度优化
Android性能优化之启动速度优化 Android app 启动速度优化,首先谈谈为什么会走到优化这一步,如果一开始创建 app 项目的时候就把这个启动速度考虑进去,那么肯定就不需要重新再来优化 ...
- unity3d android 优化
最近项目进入收尾阶段,之前对项目做了很多优化,mesh合并 ,减少DrawCall和模型骨骼以及物理计算,合并材质球,优化代码等等,在IOS上还好,但是android上,试过几款手机,从低端到高端,发 ...
- Android优化
ListView的优化 复用convertview , 历史的view对象 减少子孩子查询的次数 viewholder 异步加载数据(把图片缓存) 条目多时分页加载数据 加载时显示进度条让用户等待 I ...
- Glow Android 优化实践
了解 Glow 的朋友应该知道,我们主营四款 App,分别是Eve.Glow.Nuture和Baby.作为创业公司,我们的四款 App 都处于高速开发中,平均每个 Android App 由两人负责开 ...
- Android 优化布局层次结构
前面介绍过使用HierarchyViewer和Android lint来优化我们的程序,这一篇算是总结性的,借助一个小例子来说用怎么优化应用布局.这个例子是android官网给出的,作者也当一把翻译. ...
- Android优化—— Google 发布 Android 性能优化典范
阅读目录 0)Render Performance 1)Understanding Overdraw 2)Understanding VSYNC 3)Tool:Profile GPU Renderin ...
- Android优化——UI优化(三)使用ViewStub延迟加载
使用ViewStub延迟加载 1.ViewStub延迟加载 ViewStub是一个不可见的,大小为0的View,最佳用途就是实现View的延迟加载,在需要的时候再加载View,可Java中常见的性能优 ...
- Android优化——UI优化(一)优化布局层次
优化布局层次 1.避免布局镶嵌过深(如下) <LinearLayout xmlns:android="http://schemas.android.com/apk/res/androi ...
- Android优化系列之ListView优化老生常谈
本文内容:adapter,listview的优化,RecycleBi,google大会推荐优化, 实现ListView的过程,Adapter起到了至关重要的作用,不仅仅因为getview()方法.那么 ...
随机推荐
- GPT-3被超越?解读低能耗、高性能的GlaM模型
原创作者 | LJ GLaM: Efficient Scaling of Language Models with Mixture-of-Experts https://arxiv.org/pdf/2 ...
- Jmeter压测场景及结果分析
1)压力测试分两种场景: 一种是单场景,压一个接口的: 第二种是混合场景,多个有关联的接口. 压测时间,一般场景都运行10-15分钟.如果是疲劳测试,可以压一天或一周,根据实际情况来定. 2)压测设置 ...
- 对象中的apply&call
显式绑定法 apply/call(); 通过显式绑定法可以使用另一个对象中的方法 apply/call()都是JS预定义的方法, 他们都可以用于将一个对象作为参数调用对象方法 FOR example ...
- 【简记】Linux界面连接WPA2-Enterprise Wifi
背景 公司从去年(2021)年开始使用 WPS2-Enterprise 安全方式,我的笔记本来公司就得用网线才能连(因为当时没意识到,只是以为连不上可能和驱动有关系,这是大错特错的理解..)赶上今天去 ...
- tensorflow源码解析之common_runtime拾遗
把common_runtime中剩余的内容,按照文件名排序进行了简单的解析,时间原因写的很仓促,算是占个坑,后续有了新的理解再来补充. allocator_retry 有时候内存分配不可能一次完成,为 ...
- KDT入门小讲
KDT入门小讲 为了搞讲课两天搞出来的PPT,质量不高,随便看看 附:讲课用PPT 链接: https://pan.baidu.com/s/1qHea0fEhscAsQh8-Yu_j_A 提取码: 4 ...
- Kernel pwn 基础教程之 ret2usr 与 bypass_smep
一.前言 在我们的pwn学习过程中,能够很明显的感觉到开发人员们为了阻止某些利用手段而增加的保护机制,往往这些保护机制又会引发出新的bypass技巧,像是我们非常熟悉的Shellcode与NX,NX与 ...
- ArcMap线上均匀生成点
面中均匀生成点方法: [创建渔网]→[要素转点](或[要素折点转点])→[裁剪](或[按位置选择]→[导出数据]),即可. ArcMap中随机生成点: [随机生成点]工具 最近博主的朋友有均匀布点的需 ...
- [转载]Linux后门整理合集(脉搏推荐)
我在思考要不要联系下....都禁止转载了.... 简介 利用 Unix/Linux 自带的 Bash 和 Crond 实现远控功能,保持反弹上线到公网机器. 利用方法 先创建 /etc/xxxx 脚本 ...
- 最新出炉的Java面试题(2022亲身经历)
面试题清单 个人近来面试了不少的公司的,该挂的挂,该应付通过的应付通过,目前对面试题部分做一个系统的总结.最起码要保证被问过的问题第二次被问到的时候是可以回答并且理解的.算是一个被动输入学习的过程. ...