一、前言

首先,我们先提出一个问题,为什么要做启动优化?

随着项目的迭代,App的功能越来越丰富,无可避免的是我们将会引入更多的第三方库及各种SDK,因此App在启动时要做的初始化工作也会更繁重,不当的初始化行为就会拖慢App的启动响应速度,给用户带来糟糕的使用体验。

既然是启动优化,我们就需要先了解应用的启动类型:

  • 冷启动 :应用从头开始启动,系统进程在冷启动后才创建应用进程,发生冷启动的情况包括应用自设备启动后或系统终止应用后首次启动。
  • 热启动 :将处于后台中的应用进程恢复显示到前台,如果应用中的所有Activity都还驻留在内存中,则应用可无须重复对象初始化、布局扩充和呈现。
  • 温启动 : 应用进程还在,但activity已经从栈中推出销毁,再次启动应用需要重新创建对象。

冷启动流程图:

冷启动的链路包含热启动和温启动,因此启动优化主要是对冷启动而言。

熟悉Android系统启动流程的小伙伴知道直到我们点击Launcher上的应用启动图标,才真正的进入到App的启动流程,即从此节点之后才是我们的可控范围,由此可以引出第一个启动优化点黑白屏优化 ,此优化方案虽然不能缩短App的启动时间,但从App交互设计上给予了用户及时的操作反馈,提升了一些用户体验。由于之前介绍过相关知识点,大家可点击链接查看,本篇中不再赘述,接下来正式开始介绍启动优化。

二、启动优化

2.1 启动时间测量

测量启动时间的目的有两个:

  1. 找到需要优化的点,即哪里耗时严重
  2. 启动优化效果验证,是否达到预期时间

时间测量方式:

  • 系统日志输出

在Android 4.4及以上版本,App启动时会在logcat输出一行日志,会打印出名为Displayed的值,此值代表从进程启动到在屏幕上完成对应Activity的绘制所经过的时间。

  • adb命令
#com.example.test : 包名
#MainActivity :App的启动Activity
adb shell am start -W com.example.test/.MainActivity

点home键推到后台,再运行adb命令:

点back键推到后台,再运行adb命令:

在此我们也验证了不同启动方式的差异:冷>温>热

  • 手动(代码)获取

手动添加log日志,打印时间戳。优点:可在线上使用。 缺点:只能记录应用内耗时。

2.2 方法耗时统计

  • traceview统计

可以用代码统计或AndroidStudio自带的cpu profiler。

public class App extends Application {@Overridepublic void onCreate() {super.onCreate();//文件名,文件路径:扩展存储路径(sdcard)Debug.startMethodTracing("spend_time");////各种初始化代码//Debug.stopMethodTracing();}

橙色:系统代码调用

绿色:自己代码调用

蓝色:第三方代码调用

用as自带cpu profiler的话,需提前开启设置

可以查看耗时数据,工具具体使用方法大家可自行学习。  需要注意的是此工具对代码的侵入性较高,会拖慢代码的运行速度,所以真实耗时会稍小一点,不过不影响我们分析问题。

  • systrace统计

需要python脚本来记录,Android9.0及以上版本的设备可以开启跟踪记录。官方文档

添加跟踪代码,并运行到设备。

public class App extends Application {@Overridepublic void onCreate() {super.onCreate();//Debug.startMethodTracing("spend_time");////各种初始化代码////Debug.stopMethodTracing();Trace.beginSection("spend_time1");////各种初始化代码//Trace.endSection();}
}

然后进入到systrace.py文件所在路径,(替换成自己的sdk路径)

/Users/zhoumohan/Library/Android/sdk/platform-tools/systrace

运行命令:

python systrace.py -a 应用包名 -o mynewtrace.html sched freq idle am wm gfx view binder_driver hal dalvik camera input res

可能会报错:

ImportError: No module named six

解决方案

随后重新运行,会生成跟踪记录:mynewtrace.html,可在浏览器查看

  • aop方式统计

通过自定义注解及AspectJ框架,对需要检测的方法的前后进行代码注入,从而统计执行耗时,大家可参考AOP思想实现集中式登录,用户行为统计框架,或自行学习相关知识点,这里就不做展开。

2.3 优化方式

  • 按需初始化

此处针对于多进程App,我们知道进程是相互隔离的,所以有多少个进程,项目中的Application就会被执行多少次,因此我们可以根据不同的进程进行对应的初始话操作。

public class App extends Application {@RequiresApi(api = Build.VERSION_CODES.P)@Overridepublic void onCreate() {super.onCreate();String processName = getProcessName();if (processName != null) {if (processName.equals("进程名称")) {//...需要在不同进程下运行的代码}}}
}

示例中获取进程名适用于9.0及以上,适配低版本可参考android 获取当前进程的名称

  • 异步初始化

主要是通过使用多个子线程来初始化,达到并行执行,缩短运行时间的目的。

public class App extends Application {ExecutorService executorService;int coreSize;@Overridepublic void onCreate() {super.onCreate();coreSize = Runtime.getRuntime().availableProcessors();executorService = Executors.newFixedThreadPool(Math.max(2,Math.min(coreSize-1,4)));asyncInit(new Runnable() {@Overridepublic void run() {//SDK1.init()}});asyncInit(new Runnable() {@Overridepublic void run() {//SDK2.init()}});//等等初始化操作...}private void asyncInit(Runnable runnable){executorService.submit(runnable);}}

需要注意一下的是,放到各个子线程进行初始化的代码有没有先后顺序和调用关系,相关的初始话最好放到一个线程中,来保证代码的逻辑正确性,做异步优化时应考虑清楚一下几点:

  1. 能不能做异步优化
  2. 执行的方法是否有先后顺序
  3. 异步后代码是否能正确执行
  • 延迟初始化

即仅初始化立即需要用到的对象,不要创建全局静态对象,而是移动到单例模式,在程序第一次使用它的时候进行初始化。

  • 空闲时初始化

监听应用空闲时间,在空闲时间进行初始化。这里用到了IdelHandle的特性。

public class DelayInit {private Queue<Runnable> delayQueue = new LinkedList<>();public void add(Runnable runnable){delayQueue.add(runnable);}public void start(){Looper.myQueue().addIdleHandler(() -> {Runnable poll = delayQueue.poll();if (poll != null){poll.run();}return !delayQueue.isEmpty();});}
}

同时也需要注意初始化对象和使用对象的时序性。

Android:启动优化相关推荐

  1. android布局优化方案,Android启动优化-布局优化

    Android启动优化-布局优化 安卓应用开发发展到今天,已经成为一个非常成熟的技术方向,从目前的情况看,安卓开发还是一个热火朝天的发展,但高级人才却相对较少,如今移动互联网的开发者也逐渐开始注重插入 ...

  2. Android 启动优化(五)- AnchorTask 1.0.0 版本正式发布了

    今天,更新一下 Android 启动优化有向无环图系列的最后一篇文章.最近一段时间,暂时不会更新这方面的文章了.系列文章汇总如下: Android 启动优化(一) - 有向无环图 Android 启动 ...

  3. 深入探索Android 启动优化(七) - JetPack App Startup 使用及源码浅析

    本文首发我的微信公众号:徐公,想成为一名优秀的 Android 开发者,需要一份完备的 知识体系,在这里,让我们一起成长,变得更好~. 前言 前一阵子,写了几篇 Android 启动优化的文章,主要是 ...

  4. 启动优化·基础论·浅析 Android 启动优化

    " [小木箱成长营]启动优化系列文章(排期中): 启动优化 · 工具论 · 启动优化常见的六种工具 启动优化 · 方法论 · 这样做启动优化时长降低 70% 启动优化 · 实战论 · 手把手 ...

  5. Android 启动优化(一) - 有向无环图

    前言 说到 Android 启动优化,大家第一时间可能会想到异步加载.将耗时任务放到子线程加载,等到所有加载任务加载完成之后,再进入首页. 多线程异步加载方案确实是 ok 的.但如果遇到前后依赖的关系 ...

  6. Android启动优化实战(有效降低APP启动时间)

    1.概述 手机点击一个APP,用户希望应用能够及时响应并快速加载.启动时间过长的应用不能满足这个期望,并且可能会令用户失望.这种糟糕的体验可能会导致用户在 Play 商店针对您的应用给出很低的评分,甚 ...

  7. android 启动优化方案,Android 项目优化(五):应用启动优化

    介绍了前面的优化的方案后,这里我们在针对应用的启动优化做一下讲解和说明. 一.App启动概述 一个应用App的启动速度能够影响用户的首次体验,启动速度较慢(感官上)的应用可能导致用户再次开启App的意 ...

  8. Android 启动优化(一)

    声明:本篇文章已授权微信公众号 YYGeeker 独家发布. 前言 对于一个APP来说,启动秒开,切换顺畅的体验能给用户留下良好的第一印象,启动速度对于用户体验及提高用户留存的重要性不言而喻.那么我们 ...

  9. Android启动优化方案调研

    /   今日科技快讯   / 7月21日,国家互联网信息办公室依据<网络安全法><数据安全法><个人信息保护法><行政处罚法>等法律法规,对滴滴全球股份 ...

  10. Android 启动优化总结

    前言 性能优化包括很多方面,比如:启动优化.布局优化.内存优化.卡顿优化.网络优化.数据库优化.内存泄漏优化.包体积优化等等. 冷启动.温启动.热启动 首先了解下启动的这三个概念,也是面试常被问到的: ...

最新文章

  1. iOS UI基础-11.0 UINavigationController
  2. 同一台服务器上面安装多个mysql数据库
  3. 我的中年危机来得很自然
  4. php 链接文件名_7、php-fpm进程管理
  5. 【Modern OpenGL】Shader
  6. java使窗体最大化_[转]java窗体运行时最大化及关闭方法示例
  7. 获取客户端网卡MAC地址和IP地址的几种方法(一)
  8. 20190226-SecureCRT连接linux显示中文乱码
  9. Kotlin协程简介(一) Hello,coroutines!
  10. 人生每一件事都是为自己而做
  11. 各种常用的默认端口号归纳
  12. 今天发布《看图玩儿》看图软件
  13. python基于qq邮箱群发邮件
  14. Matlab画的玫瑰花
  15. 2020第四届全球程序员节观后感
  16. 恒生电子实习记录-10
  17. charles手机抓包配置
  18. 不用傅里叶变换,提取某一频率的幅值和相位
  19. Python基础知识学习(六)——包与模块:指令、包加载步骤、搜索范围
  20. IDEA 中内容辅助键和快捷键

热门文章

  1. 计算机网怎样连接网络连接不上,网络连接不上,详细教您电脑网络连接不上怎么解决...
  2. (转)逃脱者可获生机(中)
  3. mysql数据库:varchar类型可以存储多少个汉字,多少个数字
  4. 修改mac地址导致计算机无法上网,win7系统更换MAC地址解决无法连接网络问题的解决方法...
  5. 集美大学第七届团体程序设计天梯赛第二场排位赛题解
  6. 进销存管理系统大全【70个进销存系统】
  7. 小程序前端获取手机号码
  8. windows安装cygwin
  9. 蜂窝六边形的六边形消除高分秘籍
  10. python ssologin_Python sso