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

news2024/12/26 16:57:26

在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初始化和首屏绘制的时间。

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

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

相关文章

使用 GaLore 预训练LLaMA-7B

项目代码&#xff1a; https://github.com/jiaweizzhao/galorehttps://github.com/jiaweizzhao/galore 参考博客&#xff1a; https://zhuanlan.zhihu.com/p/686686751 创建环境 基础环境配置如下&#xff1a; 操作系统: CentOS 7CPUs: 单个节点具有 1TB 内存的 Intel CP…

F12抓包11:UI自动化 - Recoder(记录器)

课程大纲 使用场景&#xff08;导入和导出&#xff09;: ① 测试的重复性工作&#xff0c;本浏览器录制并进行replay&#xff1b; ② 导入/导出录制脚本&#xff0c;移植后replay&#xff1b; ③ 导出给开发进行replay复现bug&#xff1b; ④ 进行前端性能分析。 1、录制脚…

kubernetes 学习 尚硅谷

出自 https://www.bilibili.com/video/BV13Q4y1C7hS 相关命令 kubeadm init &#xff1a;将当前节点创建为主节点 kubectl get nodes&#xff1a;获取集群所有节点 kubectl apply -f xxx.yaml&#xff1a;根据配置文件&#xff0c;给集群创建资源 kubectl delete -f xx.yaml&…

【C++】模板进阶:深入解析模板特化

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理模板初阶String使用String模拟实现Vector使用及其模拟实现List使用及其模拟实现容器适配器Stack与Queue 本章将…

判断关系模式的无损连接(表格法)

目录 前言 一、什么是无损连接&#xff1f; 二、如何判断无损连接&#xff1f; 1.表格法 2.示例题 D选项构造初始的判断表如下&#xff1a; 总结 前言 在数据库设计中&#xff0c;确保数据的完整性和有效性是至关重要的。在关系数据库中&#xff0c;函数依赖和无损连接是…

docker|Oracle数据库|docker快速部署Oracle11g和数据库的持久化(可用于生产环境)

一、 容器数据持久化的概念 docker做为容器化的领先技术&#xff0c;现在广泛应用于各个平台中&#xff0c;但不知道什么时候有一个说法是docker并不适用容器化数据库&#xff0c;说容器化的数据库性能不稳定&#xff0c;其实&#xff0c;这个说法主要是因为对docker的数据持…

零基础5分钟上手亚马逊云科技-利用API网关管理API

简介 欢迎来到小李哥全新亚马逊云科技AWS云计算知识学习系列&#xff0c;适用于任何无云计算或者亚马逊云科技技术背景的开发者&#xff0c;通过这篇文章大家零基础5分钟就能完全学会亚马逊云科技一个经典的服务开发架构方案。 我会每天介绍一个基于亚马逊云科技AWS云计算平台…

C语言 ——— 编写代码,将一个长整数用逗号隔开,每3位一个逗号,并输出打印

目录 题目要求 代码实现 题目要求 对于一个较大的整数 N (1 < N < 2,000,000,000) &#xff0c;将 N 每个 3 位加上一个逗号&#xff0c;并且最后输出打印 举例说明&#xff1a; 输入&#xff1a;1980364535 输出&#xff1a;1,980,364,535 代码实现 代码演示&#…

详解JUC

Java并发工具包&#xff08;Java Util Concurrent&#xff0c; 简称JUC&#xff09;是Java提供的一组用于简化多线程编程的类和接口&#xff0c;它包含了用于线程同步、并发数据结构、线程池、锁、原子操作以及其他并发实用工具的丰富集合。 1. 线程池 线程池是 Java 并发编程…

【Go】Go语言中的数组基本语法与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

GUI编程13:JDialog弹窗

视频链接&#xff1a;15、JDialog弹窗_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1DJ411B75F?p15&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 package com.yundait.lesson04;import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; im…

为你的 Github 仓库引入自动构建的Github Pages静态页面

1. 设置config文件 在Github仓库根目录下创建_config.yml文件。其中的内容为&#xff1a; plugins:- jekyll-relative-links relative_links:enabled: truecollections: true include:- CONTRIBUTING.md- README.md- LICENSE.md- COPYING.md- CODE_OF_CONDUCT.md- CONTRIBUTI…

通过解预测和机器学习促进蚁群优化

文章目录 Abstract1. Introduction2. Background and related work2.1 定向越野问题2.2 ACO优化Abstract ML - ACO 算法的第一阶段,使用一组已知最优解的小定向越野问题实例训练一个 ML 模型。具体来说,使用分类模型根据问题特定的特征和统计度量来判断一条边是否属于最优路…

SSH工具 MobaXterm的使用与快捷配置

软件下载/安装与链接服务器/本地虚拟机 文章目录 软件下载/安装与链接服务器/本地虚拟机软件下载软件安装使用软件链接非本地机器并设置用户密码我不想有确定密码的弹窗 其余便捷配置配置右键粘贴SSH链接设置 软件下载 如果你访问不了这个网址&#xff0c;可以评论区找博主或者…

黑神话悟空黑风山攻略

在黑神话悟空中&#xff0c;玩家一开始来到黑风山的地图就会站在前山土地庙。 下面小编将会根据黑风山地图的地标来进行路线攻略推荐&#xff0c; 玩家可以一边查看游戏地图一边了解这些路线的动线是怎样的。 在苍狼林前山捡到药材老山参&#xff0c;跟随金色光线找到附近的土…

【机器学习】:解锁数据背后的智慧宝藏——深度探索与未来展望

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 引言一、深入机器学习的内在机制二、最新进展与趋势三、对未来社会的深远影响结语 引言 在上一篇博客中&#xff0c;我们初步探讨了机器学习如何成为解锁数据背后智慧的关键工具。现在&#xff0c;让…

网盘隐私照片泄露?教你如何保护自己的隐私照片!

网盘内的隐私照片 好兄弟最近遇到了一个困难&#xff1a;“我之前一直都是把照片存在网盘里面的&#xff0c;但是最近听说了某网盘的照片泄露了&#xff0c;自己的生活照啊&#xff0c;私密照啊都被人看光了&#xff0c;这太可怕了&#xff01;我现在也很担心自己的网盘上照片…

Android MediaPlayer + GLSurfaceView 播放视频

Android使用OpenGL 播放视频 概述TextureView的优缺点OpenGL的优缺点 实现复杂图形效果的场景参考 概述 在Android开发中&#xff0c;使用OpenGL ES来渲染视频是一种常见的需求&#xff0c;尤其是在需要实现自定义的视频播放界面或者视频特效时。结合MediaPlayer&#xff0c;我…

Java后端框架---Spring

目录 一.Spring是什么&#xff1f; 二.Spring Hello World 搭建 三.XML配置bean管理 1.bean标签 2.依赖注入 3.依赖注入的补充 四.注解配置bean管理 1.开启注解扫描 2.使用注解对类进行配置 3.自动注入 五.面向切面编程AOP 1.概述 2.通知 六.spring事务管理 1.数据库…

双三次插值及MATLAB实现

一、双三次插值的概念 双三次插值&#xff08;Bicubic interpolation&#xff09;&#xff0c;又叫双立方插值。在数值分析这个数学分支中&#xff0c;双三次插值是二维空间中最常用的插值方法。在这种方法中&#xff0c;函数f在点 (x0 ,y0) 的值不仅考虑其直接邻接点对其的影响…