Android中的冷启动,热启动和温启动

在App启动方式中分为三种:冷启动(cold start)、热启动(hot start)、温启动(warm start)

冷启动:

系统不存在App进程(App首次启动或者App被完全杀死)时启动App(后台没有该应用的进程,这时系统会又一次创建一个新的进程分配给该应用),此时,App的启动将经历两个阶段:

第一阶段:

1.加载并启动app
2.app启动后,第一时间为app显示一个空白的window
3.创建app进程

第二阶段:

系统一旦创建了app进程,app进程就要负责做以下的任务:
1.创建app对象
2.创建ActivityThread
3.创建MainActivity
4.渲染视图
5.执行onLayout
6.执行onDraw
7.完成第一次绘制后,把mainActivity替换已经展示的BackgroundWindow,即空白window。

也就是说冷启动由于系统会又一次创建一个新的进程分配给它。所以会先创建和初始化Application类,再创建和初始化MainActivity类(包含一系列的測量、布局、绘制),最后显示在界面上。

ActivityThread:负责管理应用程序的生命周期,处理消息队列,处理用户输入事件,调度Activity的创建和销毁等等。
具体来说,ActivityThread会在应用程序启动时会创建一个主线程(也就是UI线程),然后根据AndroidManifest.xml文件中声明的启动Activity,创建一个Activity对象,并通过Binder机制将这个Activity对象传递给ActivityManagerService。Activity还会负责处理Activity的生命周期,比如当用户按下返回键退出当前Activity时,ActivityThread会收到相应的消息,然后销毁当前Activity并恢复上一个Activity的状态。ActivityThread还负责处理其他一些系统事件,比如屏幕旋转、系统资源不足等等,这些事件都会通过消息队列传递给ActivityThread,然后由ActivityThread调度处理。

温启动

温启动包含在冷启动期间发生的一些操作,它的开销大于热启动(重新走 Activity 的一些生命周期,它不会重新走进程的创建、Application 的生命周期等)。由于app进程依然在,温启动只执行冷启动的第二阶段。例如:

  • 比如返回Home后,又继续使用其他的APP,时间久了或者打开的应用多了,之前应用的Activity有可能被回收了,但应用程序必须通过调用 onCreate() 重新创建Activity
  • 应用程序因为内存原因被系统强制退出,然后用户重新启动应用。进程和 Activity 需要被重新启动,但是保存的 Bundle 实例状态会被传递给 onCreate() 使用

热启动

热启动比冷启动简单得多而且开销更低,在热启动时,系统会将Activity从后台切回到前台,如果应用的所有Activity仍旧留在内存中,那么应用可以避免重复创建对象初始化,布局加载和绘制。
如果应用响应了系统内存清理的通知清理了内存,比如回调onTrimMemory(),那么这些被清理的对象在热启动就会被重新创建。也就和冷启动展示在屏幕的行为相同,系统进程会创建一个空白的屏幕直到应用绘制完成显示出Activity。

App启动优化

app启动优化的方向是冷启动。

空白window问题

app启动时,会短暂的一瞬间白屏:
在这里插入图片描述
这是我在Application的onCreate里线程休眠1s实现的。但是在实际项目中确实会存在启动白屏时间过长的问题。
为什么会有白屏?看app启动流程加载首屏部分源码:
ActivityStack


 	// Set to false to disable the preview that is shown while a new activity
    // is being started.
    private static final boolean SHOW_APP_STARTING_PREVIEW = true;
    
	void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
            boolean newTask, boolean keepCurTransition, ActivityOptions options) {
       //…… 省略一万行……

        if (!isHomeOrRecentsStack() || numActivities() > 0) {
            if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
                    "Prepare open transition: starting " + r);
            //…… 省略一万行……
            
            boolean doShow = true;
            if (newTask) {
                // Even though this activity is starting fresh, we still need
                // to reset it to make sure we apply affinities to move any
                // existing activities from other tasks in to it.
                // If the caller has requested that the target task be
                // reset, then do so.
                if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
                    resetTaskIfNeededLocked(r, r);
                    doShow = topRunningNonDelayedActivityLocked(null) == r;
                }
            } else if (options != null && options.getAnimationType()
                    == ActivityOptions.ANIM_SCENE_TRANSITION) {
                doShow = false;
            }
            if (r.mLaunchTaskBehind) {
                // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
                // tell WindowManager that r is visible even though it is at the back of the stack.
                r.setVisibility(true);
                ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
			// 如果同时满足,则显示空白屏幕
            } else if (SHOW_APP_STARTING_PREVIEW && doShow) {
                //……
                //显示空白屏幕
                r.showStartingWindow(prev, newTask, isTaskSwitch(r, focusedTopActivity));
            }
        } else {
            // If this is the first activity, don't do any fancy animations,
            // because there is nothing for it to animate on top of.
            ActivityOptions.abort(options);
        }
    }

在源码在可以看到,显示白屏由两个变量决定SHOW_APP_STARTING_PREVIEW && doShow,SHOW_APP_STARTING_PREVIEW 表示activity启动前是否显示预览;doShow,其默认值为true,但是它由newTask决定,是否为一个全新的activity栈,也就是说,SHOW_APP_STARTING_PREVIEW为true,并且app冷启动,就显示白屏。
那么能不能让用户不显示白屏呢?
由两种方法:
1.禁用app启动时window预览的功能
在主题中为首屏activity添加一个注意禁用window预览的功能,并在manifest中使用

<resources>
    <!--Base application theme-->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!--Customize your theme here.-->
        <item name="colorPrimary">@color/mainColor</item>
        <item name="colorPrimaryDark">@color/red</item>
        <item name="colorAccent">@color/black</item>
    </style>

    <!--禁用预览功能主题-->
    <style name="AppSpalshNoPreviewTheme" parent="AppTheme">
    	<item name="android:windowFullscreen">true</item>
        <item name="windowNoTitle">true</item>
        
        <!--        <item name="android:windowContentOverlay">@null</item>-->
        <!--        <item name="android:windowBackground">@mipmap/wall</item>-->
        <item name="android:windowDisablePreview">true</item>
    </style>
</resources>

在这里插入图片描述
这个时候你会发现点击了app,过了1秒多才启动,因为我们让本来显示的空白预览页面不展示了。
2.给空白首屏Activity设置一个背景
在style.xml中给SplashActivity添加一个新主题,设置一个背景:

    <style name="AppSpalshNoPreviewTheme" parent="AppTheme">
        <item name="android:windowBackground">@mipmap/aliyun</item>
        <item name="android:windowFullscreen">true</item>
        <item name="windowNoTitle">true</item>
<!--        <item name="android:windowDisablePreview">true</item>-->
    </style>

在这里插入图片描述
会发现点击了之前的空白页面换成了背景图。
从上面冷启动的介绍可知,app启动过程中,会有如下过程
在这里插入图片描述
app启动过程中,显示白屏,首屏第一次绘制完成,就会替换白屏。也就是说在首屏显示之前,都是白屏。
所以,要想解决白屏的问题,就要减少白屏显示的时间,也就是说要加快app初始化和首屏绘制的时间。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AcWing算法基础课-789数的范围-Java题解

大家好&#xff0c;我是何未来&#xff0c;本篇文章给大家讲解《AcWing算法基础课》789 题——数的范围。本文详细解析了一个基于二分查找的算法题&#xff0c;题目要求在有序数组中查找特定元素的首次和最后一次出现的位置。通过使用两个二分查找函数&#xff0c;程序能够高效…

Mysql InnoDB 存储引擎简介

InnoDB 存储引擎是 Mysql 的默认存储引擎&#xff0c;它是由 Innobase Oy 公司开发的 Mysql 为什么默认使用 InnoDB 存储引擎 InnoDB 是一款兼顾高可靠性和高性能的通用存储引擎 在 Mysql 5.5 版本之前&#xff0c;默认是使用 MyISAM 存储引擎&#xff0c;在 5.5 及其之后版…

车型展示+接驳体验!苏州金龙海格客车闪耀汉诺威商用车展

德国当地时间9月16日&#xff0c;IAA汉诺威商用车展媒体日活动在德国汉诺威展览中心开幕。该展会自1897年首次举办以来&#xff0c;已有超过一个世纪的历史&#xff0c;是全球历史最长、规模最大、最具影响力的专业商用车展之一&#xff0c;更是世界商用车行业技术创新和发展趋…

实战案例(5)防火墙通过跨三层MAC识别功能控制三层核心下面的终端

如果网关是在核心设备上面&#xff0c;还能用MAC地址进行控制吗&#xff1f; 办公区域的网段都在三层上面&#xff0c;防火墙还能基于MAC来控制吗&#xff1f; 采用正常配置模式的步骤与思路 &#xff08;1&#xff09;配置思路与上面一样 &#xff08;2&#xff09;与上面区…

STM32 如何生成随机数

目录 一、引言 二、STM32 随机数发生器概述 三、工作原理 1.噪声源 2.线性反馈移位寄存器&#xff08;LFSR&#xff09; 3.数据寄存器&#xff08;RNG_DR&#xff09; 4.监控和检测电路&#xff1a; 5.控制和状态寄存器 6.生成流程 四、使用方法 1.使能随机数发生器 …

C++笔记---二叉搜索树

1. 二叉搜索树的概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: • 若它的左子树不为空&#xff0c;则左子树上所有结点的值都小于等于根结点的值。 • 若它的右子树不为空&#xff0c;则右子树上所有结点的值都大于等于…

数据结构—双向链表

结构 带头链表里的头结点&#xff0c;实际为“哨兵位”&#xff0c;哨兵位结点不存储任何有效元素&#xff0c;只是站在这里“放哨 的” 实现双向链表 List.h #pragma once#include<stdio.h> #include<stdlib.h> #include<assert.h> #include<stdbool…

“RISCV+AI”

概述 设计方案 主要有两种设计方案。 RISCV核ASIC RISCV核是标准的基于RISCV指令集的CPU设计&#xff0c;ASIC部分通常是基于RISCV自带的向量扩展指令集构建的向量处理器&#xff0c;或是自定义的矩阵计算单元。 根据CPUAI ASIC部件的接口可以分为紧耦合和松耦合的设计1。 …

基于python+django+vue的学生管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于协同过滤pythondjangovue…

【Python笔记】PyCharm大模型项目环境配置

一、PyCharm创建新项目 二、更新pip版本 ...>python.exe -m pip install --upgrade pip 三、生成所需requirements配置文件 ...>pip freeze > requirements.txt 四、安装所需组件requirements.txt ...>pip install -r requirements.txt

【Kubernetes】linux centos安装部署Kubernetes集群

【Kubernetes】centos安装Kubernetes集群 1、环境准备 系统centos7 配置yum源参考文章 Centos系统换yum源 yum -y update 步骤1-3是所有主机都要配置&#xff0c;主机名和hosts配置完后可以使用工具命令同步 1.1 主机 一主二从 主机名ipk8smaster192.168.59.148k8snode11…

Node.js 安装及项目实践

node.js安装 node安装&#xff0c;选择版本 一直next&#xff0c;或者自己修改路径&#xff0c;添加两个包 选择自己的安装的node的路径&#xff0c;cmd或者winr cmd 显示node与npm的版本号 node -vnpm -v可以跟着这个博客将node安装 2024最新版Node.js下载安装及环境配…

ZW3D二次开发_UI_非模板表单_设置表单显示位置

1.ZW3D弹出非模板表单时可以设置弹出位置&#xff08;居中、左下角、右上角等&#xff09; 2.假设已创建好非模板表单 3.在Form属性中添加form_pos属性 4.输入值 base,CTR,0.0 &#xff0c;如下图 也可以设置为其他值显示在不同的位置&#xff0c;如下 5.重新编译&#xff0c;…

新升级|优化航拍/倾斜模型好消息,支持处理多套贴图模型!

【天元轻量化软件】一直在不断地追求进步和完善&#xff0c;以满足更多用户的各种需求。 电脑登录天元官网免费体验&#xff1a;天元轻量化软件官网 本次我们对“智能PBR”功能进行了更新。更新后的“智能PBR”支持带多套贴图的模型进行使用。 本轮更新后&#xff0c;主要受益…

防火墙--NAT技术,基于源NAT,NAT服务器,双向NAT

文章目录 防火墙--NAT技术一、基于源NAT**方式**&#xff1a;NAT No-PATNAPT出接口地址方式Smart NAT三元组 NAT 二、基于服务器的NAT多出口场景下的NAT Server 三、双向NAT 防火墙–NAT技术 基于源NAT&#xff1a;用于将内部网络的私有IP地址转换为公共IP地址&#xff0c;以便…

51单片机应用开发---数码管的控制应用

实现目标 1、掌握数码管结构、驱动原理及应用&#xff1b; 2、掌握数码管段码表推导&#xff1b; 3、会编程让开发板8个数码管动态显示。 一、什么是数码管&#xff1f; 1.数码管定义 数码管&#xff0c;也称为LED数码管&#xff0c;基本单元是发光二极管(LED)。分为七段数…

【机器学习】--- 自监督学习

1. 引言 机器学习近年来的发展迅猛&#xff0c;许多领域都在不断产生新的突破。在监督学习和无监督学习之外&#xff0c;自监督学习&#xff08;Self-Supervised Learning, SSL&#xff09;作为一种新兴的学习范式&#xff0c;逐渐成为机器学习研究的热门话题之一。自监督学习…

某思CMS V10存在SQL注入漏洞

Fofa: product"魅思-视频管理系统" 框架:ThinkPHP 5,6 1 漏洞分析&复现 位于 /controller/Api.php 控制器中的getOrderStatus 方法POST传入&#xff0c;然后直接拼接了 orderSn 变量到 where 查询中&#xff0c;导致漏洞产生. /** * 查询订单支付状态 */ pub…

服务器——装新的CUDA版本的方法

服务器——装新的CUDA版本 一、进入 CUDA 版本列表二、根据自己服务器&#xff0c;选择对应的版本和配置三、使用管理员用户&#xff0c;运行下载和安装命令四、查看显卡驱动是否安装4.1 若安装了显卡驱动4.2 若显卡驱动没安装 参考文章 一、进入 CUDA 版本列表 CUDA Toolkit …

sqlgun靶场攻略

步骤一&#xff1a;打开页面 步骤二&#xff1a;测试回显点 -1union select 1,2,3# 步骤三&#xff1a;查看数据库名 -1union select 1,2,database()# 步骤四&#xff1a;查看表名 -1union select 1,2,group_concat(table_name) from information_schema.tables where table…