ActivityThread, ActivityManagerService,ApplicationThread经典字段和方法走读

前言

继上一篇《这一次,让SystemServer, SystemServiceManager,SystemService不可能再记混》后,我还是按照这种近似对比的方式来介绍,也便于理解跟区分.

  • ActivityThread, ActivityManagerService,ApplicationThread都是些什么东西?内部执行逻辑以及之间的交互又是怎样的?
  • ActivityThread是线程Thread吗,那ApplicationThread呢?ActivityManagerService是Service吗?
  • ActivityThread的main到底什么地方触发执行?attach方法传参数不同会怎样?
  • ActivityThread#main会初始化looper,跟前面SystemServer#run里的looper有什么区别或者联系?

让我们一个个来!

ActivityThread

ClientTransactionHandler子类,而ClientTransactionHandler是抽象类.

告诉我,ActivityThread是线程吗,不是!

从源码的注释翻译过来:管理在应用进程中主线程的执行,根据活动管理器的请求调度并执行Activity、BroadtCast和其他操作.

构造方法和初始化

构造方法相对简洁,只对资源管理对象字段作了初始化.

搜索调用链发现,ActivityThread的构造方法在两处被执行,分别是静态方法mainsystemMain方法

经典成员

  • mSystemContext:ContextImpl,在getSystemContext方法被调用时初始化
  • mAppThread:ApplicationThread类型,成员初始化
  • mLooper:Looper类型,取当前所在线程
  • mH字段:H,Handler实现类,和ApplicationThread交互,详见mH.send/removeMessage或者mH.post调用
  • mExecutor字段:HandlerExecutor,实现Executor接口,但全部交由Handler字段(也就是前面的mH)完成任务处理,最终交给这个线程服务的运行在主线程上
  • mInitialApplication:Application
  • mInstrumentation:Instrumentation

main方法

执行流程

归结起来大概是:

  1. 安装选择性系统调用拦截和用户沙盒初始化
  2. 用主线模块中每个进程启动时需要调用的各种初始化API
  3. 设置当前线程为应用的主线程,内部设置false让looper内部消息队列不能退出(详情参考消息传递机制.md内Looper相关介绍),使其能够处理UI事件和应用程序的消息。
  4. 创建ActivityThread对象去执行attach,指定非系统调用
  5. 主线程Looper循环启动,应用主线程开始接收消息

调用时机:系统特殊轻量进程调用

回顾之前分享的Zygote进程启动,我们需要知道在app_main.cpp里,声明了启动参数里当携带--zygote后,会启用zygote模式,最终执行ZygoteInit.main方法.否则会走另一个分支RuntimeInit.而这次我们关注的就是RuntimeInit分支.

具体步骤:

  1. app_main.cpp的main方法作为入口,解析参数
  2. 不携带--zygote参数后,确认使用非zygote模式,这里setClassNameAndArgs将设置类名,而ActivityThread的包名路径将在这里被传入(但真的没翻到最上游的传值)
  3. 执行RuntimeInit分支,最后也是走到main方法.

但这个跟ActivityThread.main方法的执行有什么关系?

可以告诉大家,ActivityThread的main方法并没有直接编码在android系统源码里,而是使用了参数的形式从app_main.cpp里传给RuntimeInit类,由RuntimeInit类的main方法在合适时机调用内部findStaticMain方法,开始执行ActivityThread类的main方法.

这里一开始我是想从native层的代码去找,但无奈查找了android15和其他版本的源码,都没有找到,有点遗憾,如果你知道的话也可以告诉我.

适用于系统直接启动指定类如命令行工具,特殊系统进程等,因为能独立的进程不需要Zygote的所有特性(如预加载大量类库),可以直接启动,更轻量级。

调用时机:常规应用启动

每个应用进程创建都需要ActivityManagerService跟Zygote进程通信,最终让Zygote进程fork出子进程.

子进程创建完成调用handleChildProc方法进行初始化,而ZygoteInit#zygoteInit内调用的RuntimeInit#applicationInit会触发执行ActivityThread#main方法.

attach方法

执行流程:

  1. 关键字段赋值
  2. 区分是否为系统进程执行不同策略
  3. 观察View视图变化

调用时机:main方法

系统直接启动独立进程,通过RuntimeInit的findStaticMain内反射调用,attach传false

由上执行流程可知将触发ActivityManagerService的attachApplication方法,并将ApplicationThread对象传入.

调用时机:systemMain方法

SystemService进程run方法内显式调用,attach传true

由上执行流程可知将触发Application对象的创建和onCreate生命周期方法.

handleXXXXActivity/Service

handle各种状态下的Activity,Service.执行Activity/Service生命周期控制内容

关于Context

ActivityThread#getSystemContext

ActivityThread#getSystemContext在SystemService#createSystemContext被调用

内部最终依赖ContextImpl#createSystemContext,new一个ContextImpl对象

ActivityThread#getSystemUiContext

最后触发的是ContextImpl#createSystemUiContext

最终调用ContextImpl.createWindowContextBase创建ContextImpl对象.该上下文是用于UI的系统上下文(具有可以主题化的资源)。

小结

  • ActivityThread实际上并非线程,并没有真正继承Thread类.
  • 构造方法被触发的场景不同,导致attach方法传不同值,将影响ActivityManagerService或者Application流程是否被执行.
  • 一个ActivityThread对应一个ApplicationThread.

ActivityManagerService

无源码注释.但不急,我们可以从源码里找到些许信息.

这是一个Service还是SystemService吗?都不是.看继承实现体系:

继承自IActivityManager.Stub,.Stub呀,aidl?没错!注释说明:用于与活动管理器服务交互的系统私有API,提供了从应用程序回到活动管理器的调用.

到这里,我们对该类有了初步理解:作为IActivityManager这一android接口定义语言的扩展类.

初始化时机

在SystemServer的run方法内调用startBootstrapServices间接初始化ActivityManagerService,但要借助ActivityManagerService.LifeCycle类完成.

补充:set方法让ActivityManagerService能直接操作SystemServiceManager对象.

初始化就初始化,为什么是间接初始化?嗯?

ActivityManagerService.LifeCycle作为SystemService实现类,当SystemServiceManager执行startService方法时,会先以反射形式来创建ActivityManagerService.LifeCycle类对象,再触发onStart方法(详细流程参考SystemServiceManager类的源码,在文章底部引用).

ActivityManagerService.LifeCycle类构造方法内实例化了ActivityManagerService对象,在onStart方法内会触发ActivityManagerService的start方法.

所以才有间接初始化的说法.

构造方法

明确初始化时机后看下初始化时会干什么事情,上源码:

通过构造方法提炼信息,了解关键字段(有一说一,我觉得个个都关键,都逃不了关系,你说AMS为什么重要) 摊手

经典成员

mSystemThread:ActivityThread

引用来源于ActivityThread,相当于持有了ActivityThread引用.

mInjector:Injector

(如果不是因为初始化mUiHandler字段引用到,我还真不是太想列进来)

设计意义

  • 解耦:解耦ActivityManagerService与具体的Handler和Thread实现
  • 管理:集中管理Handler和Thread的配置和初始化
  • 灵活和测试:可通过依赖注入,在不同的环境中提供不同的实现

上下文字段:Context

mContext

从外部传入的,来源于SystemServiceManager的mContext字段,mContext字段又是哪来呢?从ActivityThread来,通过SystemServiceManager的构造方法赋值.

附上代码,便于追溯:

结论:ContextImpl

mUiContext

引用来源于ActivityThread,相当于持有了ActivityThread内部用于UI显示和系统资源获取的上下文.

结论:ContextImpl

Ui处理

mUiHandler:UiHandler

Handler实现类,UiHandler使用的looper是UiThread的looper

  • 用于处理与用户界面相关的任务
  • 与其他UI相关的系统服务进行交互
  • 将某些任务切换到UI线程,以确保这些任务不会阻塞AMS的主线程.
关于UiThread

android中俗称的UI线程,用于显示UI的共享单例线程.ServiceThread子类,ServiceThread类又继承自HandlerThread.以单例形式存在系统中.

ActivtyManagerService构造方法内实例化UiHandler类型字段,如果此时系统中UiThread单例尚未初始化,则此时会触发UiThread单例的创建;如果UiThread已经存在,则只是获取其Looper实例

这是一个前台线程(构造方法里设置其优先级),此外不应安排可能花费超过几毫秒的操作,以避免UI卡顿.

流程如下:

扩展:ServiceThread

ServiceThread作为HandlerThread子类,就可以被命名,指定优先级.扩展多了一个allowIo的字段. 简单说就是为那些需要内置Looper的系统服务而创建的HandlerThread

mHandlerThread:ServiceThread

ActivityManagerService构造方法内实例化的mHandlerThread字段就是ServiceThread,也被设置成前台线程(传参).

MainHandler

用于处理与AMS核心功能相关的消息和任务。它通常在AMS的主线程上运行,负责管理应用的生命周期、任务栈、广播等核心系统功能。这点可以在Handler内部接收的消息参数后的操作体现.

其初始化依赖mHandlerThread字段的looper属性作为参数执行构造方法,由于mHandlerThread在主线程被初始化,所以其获取到的也是个主线程的looper

小结

现在,哪怕没有源码的注释,结合前面了解的信息,我们能给个稍微合适的注释(参考Cursor的回答一下):ActivityManagerService是Android系统核心服务之一,作为系统进程的一部分运行在SystemServer进程中,负责管理和协调所有应用组件的生命周期以及进程管理

回答问题,ActivityManagerService是Service吗?不是!!!

那么ActivityManagerService运行在哪个线程上呢?

既然是SystemServer类的run方法上创建,run方法由是由main调用,那就是在SystemServer进程的主线程上运行了.只是内部会创建一些工作线程,处理耗时I/O,后台任务.

ApplicationThread

作为IApplicationThread.Stub接口的实现类,基于AIDL通信。是系统服务向应用层进行Binder交互的角色

说明,ApplicationThread不是Thread!

schedulexxxx

内部各种scheduleXXX方法用于向ActivtyThread的mH字段发送消息,由mH字段交给ActivtyThread内部逻辑处理,能触发各种handleXXX方法.

疑问

ActivityThreaad初始化Looper跟SystemServer的Looper有什么区别?

现象是SystemServer的run方法里使用ActivityThread的systemMain方法,这将导致ActivityThread被创建

  • 线程角度看: SystemServer.run()方法在system_server进程的主线程中执行,在这个方法内部调用了ActivityThread.systemMain(),他们在同个线程中

  • Looper角度看: 基于上述它们在同一个线程中,所以使用的是同一个Looper实例

  • Handler角度看: SystemServer创建自己的Handler实例;ActivityThread(SystemServer)创建自己的H类实例(继承自Handler);所以是不同Handler对象

但SystemServer上的ActivityThread对象不同于应用对应的ActivityThread对象:

  1. 不是应用进程的主类
  2. 没有应用组件管理:不处理Activity、Service生命周期
  3. 无UI相关功能:系统服务进程不直接处理UI

ActivityManagerService的构造方法说是在主线程上执行,源码里哪里体现这点?

  1. ActivityManagerService构造方法由SystemServiceManager在创建后执行startService方法创建
  2. SystemServiceManager在SystemServer的run内被创建
  3. SystemServer的run方法是在main方法,即主线程触发

引用

xrefandroid.com/android-15....

xrefandroid.com/android-15....

xrefandroid.com/android-15....

xrefandroid.com/android-15....

xrefandroid.com/android-15....

xrefandroid.com/android-15....

xrefandroid.com/android-15....

xrefandroid.com/android-15....

xrefandroid.com/android-15....

xrefandroid.com/android-15....

xrefandroid.com/android-15....

xrefandroid.com/android-15....

xrefandroid.com/android-15....

相关推荐
移动开发者1号1 小时前
新建Android项目build.gradle不是以前熟悉的配置
android
tangweiguo030519872 小时前
Android Kotlin AIDL 完整实现与优化指南
android·kotlin
思想觉悟3 小时前
使用AndroidStudio阅读源码
android
智驾4 小时前
HarmonyOS 是 Android 套壳嘛?
android·harmonyos·替代·套壳
longzekai4 小时前
【重学Android】03.高版本 Android Studio 不能使用引用库资源ID的问题
android·ide·android studio
YSoup4 小时前
2025深圳中兴通讯安卓开发社招面经
android
ufo00l5 小时前
ViewModel 在什么时候被销毁
android
声知视界5 小时前
音视频基础能力之 Android 音频篇 (六):音频编解码到底哪家强?
android·音视频开发
ufo00l5 小时前
讲述EventBus和RxBus的工作模式以及和LiveData消息总栈的优劣势
android
玄之宵5 小时前
Android 回显
android·java·开发语言