【性能优化】Android冷启动优化

文章目录

    • 常见现象
    • APP的启动流程
    • 计算启动时间
      • Displayed Time
      • adb dump
    • 启动优化具体策略
    • 总结
    • 参考链接


常见现象

各种第三方工具初始化和大量业务逻辑初始化,影响启动时间,导致应用启动延迟、卡顿等现象

APP的启动流程

加载和启动应用程序;
App启动之后立即展示出一个空白的启动窗口;
创建App程序的进程;

创建App对象;
启动Main Thread;
创建启动页的Activity;
加载View;
布置屏幕;
进行初始绘制;

详细启动流程可以看这篇文章
APP启动流程

计算启动时间

看一张官图
在这里插入图片描述

上图是Google提供的冷启动流程图,可以看到冷启动的起始点时Application.onCreate()方法,结束点在ActivityRecord.reportLanuchTimeLocked()方法。

我们可以通过以下两种方式查看冷启动的耗时

Displayed Time

在Android 4.4(API级别19)及更高版本中,logcat包含一个名为Displayed的log信息,此值表示启动过程和完成在屏幕上绘制相应活动之间所经过的时间量。

	adb logcat | grep Displayed05-08 19:18:14.303   419   477 I ActivityTaskManager: Displayed ***/.ui.HomeActivity: +1s382ms

adb dump

	adb shell am start -S -W ***/.ui.HomeActivity -c android.intent.category.LAUNCHER -a android.intent.action.MAINStopping: ***Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=***/.ui.HomeActivity }Status: okLaunchState: COLDActivity: ***/.ui.HomeActivityTotalTime: 1391WaitTime: 1392Complete

ThisTime:是指调用过程中最后一个Activity启动时间到这个Activity的 startActivityAndWait调用结束;
TotalTime:是指调用过程中第一个Activity的启动时间到最后一个Activity的 startActivityAndWait结束。
WaitTime:是startActivityAndWait这个方法的调用耗时;

此方法通过终端ADB命令查看启动指定页面(应用首页)的耗时,即应用冷启动的时间。

启动优化具体策略

  1. 启动白屏或黑屏问题
    设置启动页
<style name="WelcomeTheme" parent="Theme.AppCompat.Light.NoActionBar.FullScreen"><item name="android:windowBackground">@drawable/shape_welcome</item><item name="android:windowDrawsSystemBarBackgrounds">false</item>
</style>
  1. Application启动优化
    attachBaseContext()的优化
    主要是MultiDex启动优化的,但是MultiDex启动优化存在一定风险,主dex经过一系列的优化操作减少了主dex的大小,因此也增大了NoClassDefFoundError的异常的可能,此时会导致我们的应用启动失败的风险。所以MultiDex启动优化一定要做好检查测试工作。

    onCreate()
    Application的onCreate()随着业务的复杂会存在大量的第三方库的初始化和组件初始化,导致该生命周期过于沉重,影响启动时间。对onCreate()的优化可以分为四类
    1、必须在onCreate()且是主进程中初始化
    2、可以延迟,但是需要在Application中初始化
    3、可以延迟到启动页的生命周期回调中初始化
    4、延迟到用的时候再初始化
    此处的优化着力会比较多,牵涉的代码业务逻辑比较复杂,核心是减轻冷启动初始化的工作,延迟初始化和按需初始化。

  2. 寻找有效的结束回调
    1、IdleHandler
    从冷启动流程图看,结束时间是在UI渲染完计算的,所以很明显,Activity生命周期中的onCreate()、onResume()、onStart()都不能作为冷启动的结束回调。常规操作中用Handler.postDelay()问题在于Delay的时间不固定,但我们知道消息处理机制中,MessageQueue有个ArrayList。可以在列表中添加Idle任务,Idle任务列表只有MessageQueue队列为空时才会执行,也就是所在线程任务已经执行完时,线程处于空闲状态时才会执行Idle列表中的任务。

public class MainActivity extends Activity {private static final Handler sHandler = new Handler(Looper.getMainLooper());@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {@Override    public boolean queueIdle() {   // 页面启动所需耗时初始化            doSomething();return false;}});}
}

2、onWindowFocusChanged()
在冷启动结束即UI渲染完在去处理初始化操作,也是达到延迟初始化的目的。

@Overridepublic void onWindowFocusChanged(boolean hasFocus) {    super.onWindowFocusChanged(hasFocus);    if (onCreateFlag && hasFocus) {onCreateFlag = false;sHandler.post(new Runnable() {@Overridepublic void run() {doSomething();}})}}

3、通过View.post(Runnable runnable)方法实现
View内部维护了一个HandlerActionQueue,我们可以在DecorView attachToWindow前,通过View.post()将任务Runnables存放到HandlerActionQueue中。当DecorView attachToWindow时会先遍历先前存放在HandlerActionQueue的任务数组,通过handler挨个执行。

  // 方案只有在onResume()或之前调用有效protected void postAfterFullDrawn(final Runnable runnable) {    if (runnable == null) {        return;    }    getWindow().getDecorView().post(new Runnable() {        @Override        public void run() {            sHandler.post(runnable);}    });}

总结

冷启动优化主要是两大方面一是启动页的设置;而是初始化的管理包含延迟初始化和按需初始化,根本还是减少不必要的初始化逻辑,尽量轻量化。

参考链接

  1. 【性能优化】Android冷启动优化
  2. Android应用优化之冷启动优化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/34729.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习笔记STMF4 TIMER定时器(使用开发板立创天空星STMF4)

目录 #定时器的介绍 #怎么去理解定时器的预分频系数 #使用定时器实现完成触发中断 #定时器触发中断基本函数配置 #在使用TIMER 触发中断的时候为什么不需要配置EXTI中断这个选项 #使用定时器完成输出PWM #PWM基本知识介绍 #函数配置生成PWM 这个系列所有笔记用来记录&#x…

AttributeError: module ‘cv2‘ has no attribute ‘face‘

Traceback (most recent call last): File "D:\AI_37\pythonProject7\day23\课堂代码\day23\07-人脸识别.py", line 4, in <module> recognizer cv2.face.LBPHFaceRecognizer_create() ^^^^^^^^ AttributeError: module cv2 has no at…

【OnlyOffice】 桌面应用编辑器,版本8.1发布,PDF编辑器、幻灯片版式、改进从右至左显示、新的本地化选项等功能,快来体验吧

继 ONLYOFFICE 文档 8.1 发布后&#xff0c;适用于 Linux、Windows 和 macOS 的 ONLYOFFICE 桌面应用程序最新版本也已推出。它具有在线套件的最主要功能&#xff0c;例如功能齐全的 PDF 编辑器、演示文稿中的幻灯片版式、改进的 RTL 支持、新的本地化选项等。 目录 ONLYOFFICE…

Python装饰器:深入解析与实用案例

Python装饰器&#xff1a;深入解析与实用案例 在Python编程中&#xff0c;装饰器&#xff08;Decorators&#xff09;是一个强大且优雅的功能&#xff0c;它允许我们在不修改函数或类代码的情况下&#xff0c;给它们添加额外的功能。装饰器在日志记录、性能分析、权限检查等场…

缓存穿透防御战:Memcached解决方案全解析

缓存穿透防御战&#xff1a;Memcached解决方案全解析 引言 在高性能的缓存系统设计中&#xff0c;Memcached扮演着至关重要的角色。然而&#xff0c;缓存穿透问题却可能成为系统的致命弱点。当大量请求指向不存在的数据时&#xff0c;这些请求可能直接打到数据库&#xff0c;…

手机看cad图的软件有哪些?软件推荐

手机看cad图的软件有哪些&#xff1f;随着科技的不断发展&#xff0c;CAD图纸在手机上的查看和编辑需求日益增加。为了满足这一需求&#xff0c;市面上涌现出了众多手机CAD看图软件。本文将为大家推荐四款优秀的手机CAD看图软件&#xff0c;并分别介绍它们的功能特点、受众定位…

【数组】- 有序数组的平方

1. 对应力扣题目连接 有序数组的平方 2. 实现案例代码 public class SquareOfOrderedArrays {public static void main(String[] args) {// 创建非递减数组int[] nums {-4, -1, 0, 3, 10};// 调用函数并打印结果System.out.println(Arrays.toString(sortedSquaresOfFor(num…

JavaScript的学习之DOM简介

目录 一、DOM是什么 二、节点是什么&#xff08;Node&#xff09; 三、代码示例 一、DOM是什么 DOM全称Document Object Model文档对象模型 文档&#xff1a;表示整个HTML网页文档 对象&#xff1a;表示网页中的每一个部分转换为一个对象 模型&#xff1a;表示对象之间的关系…

Python并发编程:选择最佳并发方式

Python并发编程&#xff1a;选择最佳并发方式 在Python编程中&#xff0c;并发处理是一个常见且重要的主题。随着系统需求的增长&#xff0c;单个线程或进程往往无法高效地处理所有任务&#xff0c;尤其是在需要同时处理大量独立任务时。Python提供了多种并发机制&#xff0c;…

LabVIEW开发电气设备检测与管理系统

设计并实现了一个基于LabVIEW的电气设备检测与管理系统&#xff0c;采用了先进的硬件设备&#xff08;NI PXI-6289数据采集卡、Fluke 434电能质量分析仪和Schneider PM5560电力监控仪&#xff09;&#xff0c;通过实时采集、处理与存储电气设备数据&#xff0c;提高了电气设备的…

kotlin 协程之Callback转挂起函数(suspendCoroutine)

前言 在 Kotlin 协程中可以通过挂起函数来实现异步操作的串行化,但是在日常开发场景中,大部分项目都是java和kotlin并存的,老旧的Java代码除非有需求,否则不会轻易改动重构。 即使项目是纯kotlin开发的,也会有一些java代码实现的三方库, 因此,我们很难规避掉所有的 C…

【XCharts插件】4-4、扩展图表(v3.0)

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址QQ群:398291828大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 XCharts插件是一款基于UGUI的功能强大、易用、参数可配置的数据可视化图表插件。 【Unity3D…

Go语言JSON-RPC 实战: `net/rpc/jsonrpc` 包的高效使用指南

Go语言JSON-RPC 实战&#xff1a; net/rpc/jsonrpc 包的高效使用指南 简介jsonrpc 包的基础客户端&#xff08;Client&#xff09;创建客户端调用方法 服务器&#xff08;Server&#xff09;配置服务器数据类型和错误处理 搭建基础的 JSON-RPC 服务服务端的实现客户端的实现 进…

60.Python-web框架-Django手动删除了一个数据库表,migrate问题

目录 1.问题产生 2.解决方法&#xff1a; 1.问题产生 今天手欠&#xff0c;删了一个数据库表&#xff0c;然后迁移不进来了。 当你在Django项目中手动删除了数据库模型&#xff08;models&#xff09;的表后&#xff0c;想要Django通过makemigrations命令重新创建或识别这些更…

[数据集][目标检测]斑马线人行横道检测数据集VOC+YOLO格式793张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;793 标注数量(xml文件个数)&#xff1a;793 标注数量(txt文件个数)&#xff1a;793 标注类别…

“拿来主义”学习元素裁剪(附源码)

“拿来主义”学习元素裁剪 欢迎关注&#xff1a; 小拾岁月&#xff0c;获取源码。 参考链接&#xff1a;https://mp.weixin.qq.com/s/TsOOhUAff6OeqPW7A9JuaQ 预期效果图 需求分析 首先从需求上来看&#xff0c;需要一个主元素用于展示用户头像。例外&#xff0c;在页面无操…

游戏AI的创造思路-技术基础-深度学习(3)

继续填坑&#xff0c;本篇介绍深度学习中的长短期记忆网络~~~~ 目录 3.3. 长短期记忆网络&#xff08;LSTM&#xff09; 3.3.1. 什么是长短期记忆网络 3.3.2. 形成过程与运行原理 3.3.2.1. 细胞状态与门结构 3.3.2.2. 遗忘门 3.3.2.3. 输入门 3.3.2.4. 细胞状态更新 3.…

bind call和aplly的区别

bind是异步代码&#xff0c;改变后不会立即执行&#xff1b;而是返回一个新的函数。 call和apply是改变后页面加载之后就立即执行&#xff0c;是同步代码。 call 和 apply 的相似点&#xff1a; 两者都是用来调用函数的方法。它们都允许你显式地设置函数的 this 值&#xff…

Unity通过Package Manager导入Newtonsoft.Json或叫Json.NET

Unity打开Package Manager窗口: 输入: com.unity.nuget.newtonsoft-json

个人对devops的一点见解

DevOps 是一种将开发&#xff08;Development&#xff09;和运维&#xff08;Operations&#xff09;相结合的理念和实践方法。 它强调打破开发团队和运维团队之间的传统壁垒&#xff0c;促进两个团队之间更紧密的协作和沟通&#xff0c;以实现更高效、更快速、更可靠的软件交付…