业界动态
ActivityManagerService解读之Activity启动初探
2024-11-04 17:58

Activity是Android四大组建之一,负责用户交互界面展示,其重要性不可言喻。Android系统由ActivityManagerService负责管理Activity。熟悉Activity的启动,将对我们学习了解ActivityManagerService大有裨益。本文基于AndroidP将以首次点击桌面应用图标的方式为线,分析Activity的启动,包括分析应用进程启动。文中将涉及不少应用启动的字眼,为了避免理解上的误解,先做一解释,其实应用启动的过程,便会伴随着Activity的启动,分析应用的启动流程包括Activity的启动。这里不讨论无界面应用(比如只托管service的应用进程启动,特指有界面的应用程序。由于篇幅原因文章中,只列举一些启动过程中的关键代码,将会更多介绍AMS相关的内容,至于涉及到WMS等其他内容暂不做重点讨论。我们在理解这些关键的基础上,回头再看Activity的启动将“如履平地”般容易。

ActivityManagerService解读之Activity启动初探

以小见大-以Log窥Activity启动全貌(Log来源小米8手机Android8.1系统,与P相差不大

以上这份Log基本可以说是涵盖了Acitivity启动过程中所有的关键点信息,作为初学者,可能不知所以然,不过没关系,本文将详细介绍,这其中的原理。你可以获得Activity启动的耗时时间,你可以获得Activity启动所在的Stack和归属的Task id号……

基础普及-一张小图解Activity

Activity 生命周期回调方法汇总表。 

方法说明是否能事后终止后接onCreate首次创建 Activity 时调用。 您应该在此方法中执行所有正常的静态设置 — 创建视图、将数据绑定到列表等等。 系统向此方法传递一个 Bundle 对象,其中包含 Activity 的上一状态,不过前提是捕获了该状态(请参阅后文的保存 Activity 状态)。

始终后接 onStart()。
NOonStartonReStart在 Activity 已停止并即将再次启动前调用。

始终后接 onStart()
NOonStartonStart在 Activity 即将对用户可见之前调用。
如果 Activity 转入前台,则后接 onResume(),如果 Activity 转入隐藏状态,则后接 onStop()。 
NOonResume

onStop
onResume在 Activity 即将开始与用户进行交互之前调用。 此时,Activity 处于 Activity 堆栈的顶层,并具有用户输入焦点。
始终后接 onPause()。
NOonPauseonPause当系统即将开始继续另一个 Activity 时调用。 此方法通常用于确认对持久性数据的未保存更改、停止动画以及其他可能消耗 CPU 的内容,诸如此类。 它应该非常迅速地执行所需操作,因为它返回后,下一个 Activity 才能继续执行。
如果 Activity 返回前台,则后接 onResume(),如果 Activity 转入对用户不可见状态,则后接 onStop()。
YESonResume

onStop
onStop在 Activity 对用户不再可见时调用。如果 Activity 被销毁,或另一个 Activity(一个现有 Activity 或新 Activity)继续执行并将其覆盖,就可能发生这种情况。
如果 Activity 恢复与用户的交互,则后接 onRestart(),如果 Activity 被销毁,则后接 onDestroy()。 
YESonRestart

onDestroy
onDestory在 Activity 被销毁前调用。这是 Activity 将收到的最后调用。 当 Activity 结束(有人对 Activity 调用了 finish(),或系统为节省空间而暂时销毁该 Activity 实例时,可能会调用它。 您可以通过 isFinishing() 方法区分这两种情形。YES

了解Activity,就要知道Activity的生命周期(Lifecycle,知道Activity各个生命周期出现的场景。如图所示,Activity从开始到结束可细分为:onCreate,onStart,onResume,onPause,onStop,onDestory。Activity的启动方式,显示,隐式

一般我们都是如此启动,当然我们也可以通过配置AndroidManifest我们的某个Activity作为应用启动首选Activity

 Android规定Activity有四种启动方式standard,singleTop,singleTask,singleInstance。

Android应用程序的入口ActivityThread-好比Java程序的main主函数

讲Activity启动之前,必须强调一下ActivityThread,ActivityThread的main方法便是Android应用程序的入口,代表应用程序执行开始。

Android应用程序的事件操作是基于消息机制的,简单概述一下Android的消息机制,Android消息机制三大核心Handler,MessageQueue,Loop。Handler负责处理消息,MessageQueue用来保存消息,Loop用来循环取消息。ActivityThread的main方法的最后一行Looper.loop()(这是一个死循环,后续介绍Android消息机制的时候详细解释)意思就是我们的应用进入工作循环模式,开始运行,准备接受处理消息了。直白的说就是应用跑起来了。既然应用程序已经运行起来了,那么我们就需要Activity界面展示了。我们就要启动我们的Activity了,本文将以首次点击QQ桌面图标启动QQ首Activity为线,来分析Activity的启动流程及原理。

弹指一击QQ应用桌面图标-手机系统都经历了啥

当我们首次通过点击QQ桌面图标来启动QQ应用时,QQ启动的动作请求来自桌面应用miui Launcher,经过一些列的调用,便请求AMS启动QQ应用,最终调用AMS的ActivityStarter的startActivity方法,该方法可以认为是Activity启动过程中的第一步,负责启动时最基本的检查操作,比如检查Activity信息是否存在,创建ActivityRecord等

该方法执行会输出对应Log

经过层层调用便会继续调用ActivityStarter的startActivityUnchecked方法,从命名可以看出,该方法中应该不做任何检查工作,之负责Activity启动时在AMS中的一些初始化的任务,我们知道Activity启动涉及启动flag,Task,Stack信息,我们需要做一个初始化

 startActivityUnchecked方法还会为启动的Activity创建或复用对应的Stack和Task。更多Stack和Task信息请查看文章“任务(Task)和堆栈(Stack)”google网站翻译内容,介绍的非常详细。

调用setTaskFromReuseOrCreateNewTask创建或者复用当前的启动Activity所在的Task,本例是创建。当应用内部Activity跳转排除启动模式和启动Flags干扰时,一般会复用之前Activity所在的Task。创建TaskRecod由ActivityStack.createTaskRecord完成,期间还会调用TaskRecord.createWindowContainer创建对应的TaskWindowContainerController,同时关联TaskRecord和TaskWindowContainerController,对应如下Log

当Task创建好了之后,我们已经将Task和Activity关联好,并且Task的头部Activity便是我们要启动的Activity,继续执行启动,对应Log如下

其中mTargetStack.startActivityLocked方法,对应如下Log

当我们创建设置好Task和Stack之后,我们就要真正开始resume启动激活Activity了,继续执行 mSupervisor.resumeFocusedStackTopActivityLocked最终经过层层调用直到ActivityStack的resumeTopActivityInnerLocked:这也是启动过程中第一次调用该方法,由于整个启动过程函数调用相当复杂,这里暂且先预览一下整个执行过程 

第一次调用resumeTopActivityInnerLocked,我们会发现参数prev和next都是指向要启动的QQ的SplashActivity,而当前手机显示的应用是miui launcher,因此我们在启动新的Activity之前需要暂停当前正在显示的应用,因此此时会输出对应的Log

当miui launcher成功暂停的时候,输出对应Log

接着会继续第二次执行resumeTopActivityInnerLocked去真正的启动我们的QQ,但是由于QQ首次启动,因此我们先创建其进程,当创建OK好QQ进程之后,会调用QQ进程的ActivityThread的main函数,这样QQ进程便成功启动了,对应Log

但是此时QQ应用进程在系统中的名称并未设置为对应的QQ的进程名,会在bindApplication操作中进行设置。对应Log

程创建好之后,继续Activity启动流程,从代码流程中我们可以看出最终是要执行realStartActivityLocked这个方法的,对应会输出Log

realStartActivityLocked方法中会调用stack.minimalResumeActivityLocked(r); 对应会输出Log

之后会到QQ应用进程去启动首界面SplashActivity,对应从应用程序中会输出Log

此时应用进程便会开始绘制自己的界面,并与WMS和SurfaceFlinger通信,进行界面展示,至于Activity的界面绘制流程,计划后续会再进行介绍,此处不重点分析。

任务(Task)和堆栈(Stack)-翻译自google网站

任务Task)是指在执行特定作业时与用户交互的一系列 Activity。 这些 Activity 按照各自的打开顺序排列在堆栈(Stack)中,AMS中分别以TaskRecord和ActivityStack表示,Activity则用ActivityRecord表示。

大多数情况下设备主屏幕即launcher界面,就是任务的起点,当用户触摸应用启动器中的图标(或主屏幕上的快捷方式)时,该应用的任务将出现在前台。 如果应用不存在任务(应用最近未曾使用,则会创建一个新任务,并且该应用的“主”Activity 将作为堆栈中的根 Activity 打开。

当前 Activity 启动另一个 Activity 时,该新 Activity 会被推送到堆栈顶部,成为焦点所在。 前一个 Activity 仍保留在堆栈中,但是处于停止状态。Activity 停止时,系统会保持其用户界面的当前状态。 用户按“返回”按钮时,当前 Activity 会从堆栈顶部弹出(Activity 被销毁,而前一个 Activity 恢复执行(恢复其 UI 的前一状态)。 堆栈中的 Activity 永远不会重新排列,仅推入和弹出堆栈:由当前 Activity 启动时推入堆栈;用户使用“返回”按钮退出时弹出堆栈。 因此,返回栈以“后进先出”对象结构运行。

下图 通过时间线显示 Activity 之间的进度以及每个时间点的当前返回栈,直观呈现了这种行为。

显示任务中的每个新 Activity 如何向返回栈添加项目。 用户按“返回”按钮时,当前 Activity 随即被销毁,而前一个 Activity 恢复执行。

如果用户继续按“返回”,堆栈中的相应 Activity 就会弹出,以显示前一个 Activity,直到用户返回主屏幕为止,当所有 Activity 均从堆栈中移除后,任务即不复存在。

任务是从用户角度来管理Activity的,当用户开始新的任务或者按home键回到主屏幕时,可以移到到后台,当该任务到后台时,任务中所有的Activity全部处于停止状态,但是任务的堆栈顺序是不会改变的,从window的角度来说,该任务只是失去焦点而已

两个任务:任务 B 在前台接收用户交互,而任务 A 则在后台等待恢复。

当该任务获得焦点时,用户即可回到离开时的状态。但是如果后台运行着多个任务,系统为了保持流畅性,可能会开始销毁后台的Activity,以回收内存资源,从而导致Activity的状态丢失,详细请参见Activity状态

正常情况下,由于栈中的 Activity 永远不会重新排列,因此如果应用允许用户从多个 Activity 中启动特定 Activity,则会创建该 Activity 的新实例并推入堆栈中(而不是将 Activity 的任一先前实例置于顶部,因此,应用中的一个 Activity 可能会多次实例化(即使 Activity 来自不同的任务)如下图

但是,如果我们不希望 Activity 多次实例化,则可修改此行为,详细请参见Task管理。系统中Activity和Task的默认行为如下

最新新闻
李子柒华农兄弟复出!怀旧与变迁背后的故事
2024年,李子柒和华农兄弟这对备受关注的网络红人再次归来,令人不禁感慨:时光荏苒,曾经的现象级人气竟然如同春水般涌回,与此
2024年创业新机遇,揭秘10个潜力无限的冷门生意
2024年,尽管市场充满挑战,但仍有许多不起眼的创业项目蕴含巨大潜力。以下是10个值得关注的创业好项目:,,1. **家庭清洁服务*
2025五行属什么意思2024什么命五行属性范文
1、2025五行属什么意思2024什么命五行属性 2024年为农历甲辰年,也就是纳音为佛灯火命,我们俗称这为木龙命。对此2024年的五行属什
2025市场空白的新兴行业有哪些
现在年轻的创业者很多,有学历有资金支持的年轻人,20多岁一毕业就想着自己开店创业,给自己打工。下面小编为介绍几个新兴行业创业
2025年国运预测:比2024年更艰难,绝大多数人会过得不好
创作声明:本文为虚构创作,请勿与现实关联根据一个懂命理的朋友说,2025年,90%的人会过得不顺,甚至会走入死运。当然,这里所
李子柒消失2年后,终于轮到她爆火了
“铁树银花落,万点星辰开。”这是前不久在网上疯传的一条爆款视频。传承千年的非遗绝技——打铁花,在视频里浴火重现,吸引了超
李子柒深度解读走红始末,到底打了谁的脸
最近吃瓜群众们的热情都聚焦在李子柒事件的最新进展,毕竟几千万粉丝可都盼着更新呢!更重要的是,天天网上冲浪都能看到某些人哗
知名博主跳英歌舞引关注!这届年轻人对传统文化很“上头”|文化中国行
文/羊城晚报全媒体记者 周欣怡日前,千万级粉丝博主江寻千(九月)与青年演员南笙在潮州古城演绎了一场热血澎湃的英歌舞,“中华
李子柒出任百度百科AI非遗馆荣誉馆长:希望更多人参与进来
百度百科AI非遗馆点亮仪式11月14日于成都举办,知名博主李子柒复出后再履新职,担任百度百科AI非遗馆荣誉馆长及产品共建人,同时
【文艺评论】四川日报:人们为什么喜欢李子柒?
人们为什么喜欢李子柒?边 钰 成 博李子柒的短视频饱含着中国乡村美学,舒展着田园生命。李子柒打捞出乡村秀色,小院、农作物、竹林