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....

相关推荐
薛晓刚19 分钟前
MySQL的replace使用分析
android·adb
DengDongQi41 分钟前
Jetpack Compose 滚轮选择器
android
stevenzqzq42 分钟前
Android Studio Logcat 基础认知
android·ide·android studio·日志
代码不停1 小时前
MySQL事务
android·数据库·mysql
朝花不迟暮1 小时前
使用Android Studio生成apk,卡在Running Gradle task ‘assembleDebug...解决方法
android·ide·android studio
yngsqq1 小时前
使用VS(.NET MAUI)开发第一个安卓APP
android·.net
Android-Flutter1 小时前
android compose LazyVerticalGrid上下滚动的网格布局 使用
android·kotlin
Android-Flutter1 小时前
android compose LazyHorizontalGrid水平滚动的网格布局 使用
android·kotlin
千里马-horse1 小时前
RK3399E Android 11 将自己的库放到系统库方法
android·so·设置系统库
美狐美颜sdk2 小时前
Android直播美颜SDK:选择指南与开发方案
android·人工智能·计算机视觉·第三方美颜sdk·视频美颜sdk·人脸美型sdk