Activity管理(三),腾讯T2大牛亲自教你

1.ScheduleLaunchActivity

此接口的作用在于生成一个新的本地Activity对象,并且使之进入resume状态(或pause状态)。通常AMS会在两种情况下调用这个接口:点击应用图标打开新应用;从Activity B返回Activity A时,Activity A由于内存不足被kill。至于AMS如何确定何时调用此接口,属于AMS内部对activity的调度流程,后面会分析到。

在这里先说明下ActivityThread各函数的命名规则和函数调用方式。

上面列举的几个提供个AMS的接口全都以schedule为前缀,并且所有接口都是往主线程的handler里发送了命令消息之后立刻返回。这样所有的操作都会被转移到主线程上来。对应每一个schedule***函数,都有一个响应操作的handle***函数。在handle***函数里,会根据需要把操作进一步分解成几个动作,真正面向activity的操作统一命名为perform***。在perform***函数的内部,才会真正调用activity的生命周期函数(其实是通过Insturmentation来间接调用)。所以我们可以把所有的接口和方法进行分层:schedule->handle->perform->activity/Insturmation。

在scheduleLaunchActivity中,会往主线程handler发送一个“LAUNCH_ACTIVITY”消息,然后调用handleLaunchActivity。在handleLaunchActivity内部分解成两个动作:

a) performLaunchActivity

在这里完成了activity对象的创建和activity生存环境的创建。比如application对象的生成。接着调用activity.attach()完成Window和WindowManager的创建,并且记录了activity的环境变量如mToken、mActivityInfo等。到此为止,一个具有完整功能的Activity对象已经完成了初始化,接着会调用mInstrumentation.callActivityOnCreate()和activity.performStart()分别响应属于activity生命周期的onCreate()方法和onStart()方法。

b) handleResumeActivity

这个方法属于“handle层”的另一个方法,主要完成onStart()和onResume()的响应,在第二个例子中会说明。

2.ScheduleResumeActivity

顾名思义,此方法的作用是把一个activity置于resume状态。相应的,所有操作被转移到handleResumeActivity()中。对于handleResumeActivity,有两种情况会调用此方法:scheduleResumeActivity发送“RESUME_ACTIVITY”消息;handleLaunchActivity中的第二步。

在handleResumeActivity中也进一步分解成了两个动:

a) performResumeActivity

调用activity.performResume()方法,在activity.performResume()中会默认先调用performRestart(),performRestart()的作用是先检查activity是否处于stopped状态,如果是则调用performRestart()再调用performStart()。最后再响应activity的生命周期方法onResume()。

所以,新打开一个activity的响应流程是:

onCreate()->onStart()->onResume()

而返回一个后台activity的响应流程是:

onRestart()->onStart()->onResume()

b) 完成了第一步对activity生命周期的响应之后,在第二步这里主要是处理窗口的添加动作:把DecorView添加到WindowManager中。完成第二步操作之后,activity的内容便显示到了屏幕上。这个窗口的添加动作属于窗口管理中的一个步骤,具体可参考《Android窗口管理剖析》一文。

以下是部分主要接口到生命周期的响应的内部调用流程图

img

二、ActivityManagerService及其内部调度流程

\1. 数据结构分析

和窗口管理系统一样,所有的客户端activity在ActivityManagerService(简称AMS)内部都会有一个对应的ActivityRecord,对activity的管理也就是对ActivityRecord的管理。

AMS的相关代码在framework/base/services/java/com/android/server/am,主要的数据结构有:

ActivityManagerService

ActivityStack

ActivityRecord

TaskRecord

ProcessRecord

  1. ActivityManagerService是android框架服务,主要负责处理对android四大组件的管理和响应Client端的请求。此外还包括进程的产生和对WindowManagerService的操作。

  2. ActivityStack是专门实现对ActivityRecord的堆栈式管理而分离出来的一个模块。在Android2.2以前,对ActivityRecord的管理和调度都在ActivityManagerService实现。从android2.3以后,为了实现更好的解耦把对ActivityRecord的管理单独分离出来了,所有对ActivityRecord的调度操作都在ActivityStack里进行。其实Android里所谓的“Activity堆栈”,并不是真正的一个堆栈结构,而是一个ArrayList列表,在这个列表里记录了所有的ActivityRecord,ActivityStack所做的事情就是保证列表的第一个ActivityRecord(也就是“栈顶”)处于运行状态,并且排在列表后面的ActivityRecord的运行状态受到“栈顶”ActivityRecord的影响。

  3. ActivityRecord代表了一个Client端的Activity,记录了Activity的各种属性和管理状态。其中有介个关键的成员变量:

IApplicationToken.StubappToken

appToken作为此ActivityRecord的唯一标识,贯穿了AMS、Activity和WMS。

TaskRecordtask

task标识了此ActivityRecord所属的Task。在ActivityStack对ActivityRecord的位置调整中,更多的是以TaskRecord为单位进行的。如moveTaskToFront()、moveTaskToBack()等接口,会同时移动属于同一个Task的所有activity。 TaskRecord和ActivityRecord是一对多的关系,多个ActivityRecord可能指向同一个TaskRecord

ProcessRecordapp

app标识了Client端的Activity所在的进程。同样的,ProcessRecord和ActivityRecord是一对多的关系,多个ActivityRecord可能指向同一个ProcessRecord。通过访问ProcessRecord中的IApplicationThread可以直接操作Client端的ActivityThread。

  1. TaskRecord记录了task的id、名称等属性。

我们知道,Activity的管理是以Task为单位来进行的,多个行为类似的Activity会被归类到同一个Task中。一般来说,一个apk中的所有Activity都是属于同一个Task,并且Task以apk的包名来命名。但开发者可以在AndroidManifset.xml中通过android:taskAffinity属性给每个Activity配置不同的Task。而什么时候会新开一个Task,新开Task的名字等由ActivityStack里面的逻辑来判断,具体取决于AndroidManifest.xml中的配置和调用startActivity()时传递的flag。

  1. ProcessRecord记录了进程id、进程名字和各种用于调节优先级的状态。还包含了所有运行在该进程的Activity、Service、Receiver、Provider等组件。IApplicationThread thread记录了该进程中的主线程。当一个Acitivity第一次启动时,会首先调用Process.start(“android.app.ActivityThread”)来创建一个新进程并且生成一个ProcessRecord对象。当进程运行起来之后,该进程的主线程会调用Client端的ActivityThread.main()函数,在main()函数中完成Looper的prepare(),并且生成ActivityThread对象,接着在ActivityThread.attach()中调用IActivityManager.attachApplication()回到AMS,在AMS中完成ProcessRecord和IApplicationThread对象的绑定。接下来的流程就会把新Activity和ProcessRecord绑定。

关于ActivityManagerService、ActivityStack、ActivityRecord、TaskRecord、ProcessRecord的关系可用下图表示:

img

\2. ActivityStack内部调度流程

在整个调度流程中,ActivityStack记录了列表中每个ActivityRecord的当前状态,包括这9个状态:INITIALIZING, RESUMED, PAUSING, PAUSED, STOPPING, STOPPED,FINISHING, DESTROYING, DESTROYED。每个ActivityRecord在任何时刻都处于这9个状态中的其中一个。除此以外,ActivityStack还有几个变量用于辅助调度过程的:

ActivityRecord mResumedActivity

ActivityRecord mPausingActivity

boolean finishing

boolean stopped

ArrayListmStoppingActivities

mResumedActivity指向当前系统中的“栈顶”Activity,当“栈顶”Activity将要被暂停时,mResumedActivity为空,mPausingActivity指向该被暂停的Activity,直到Client端Activity响应onPause()之后回调AMS,mPausingActivity置空。finishing和stopped是ActivityRecord的两个boolean变量,finishing为true表示该Activity将要被销毁;stopped为true表示该Activity处于stopped状态(该stopped变量和Activity的STOPPED状态有重复的嫌疑,可认为是同等的)。

ActivityStack内部的调度围绕着这9个状态来进行,下面通过例子来分析其调度流程。

从Launcher(A)打开新应用(B)

  1. 在Clien端请求打开新Activity之后,ActivityStack首先创建一个ActivityRecord并将其置于“栈顶”,此时ActivityRecord处于INITIALIZING状态。

  2. 接着调用resumeTopActivityLocked()。在resumeTopActivityLocked()中检查mResumedActivity是否为空,此时mResumedActivity指向A,所以肯定不为空。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

最后

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

上面分享的腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。

【Android思维脑图(技能树)】

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

【Android高级架构视频学习资源】

腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。

【Android思维脑图(技能树)】

知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。

[外链图片转存中…(img-mA6hca4U-1711912496099)]

【Android高级架构视频学习资源】

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值