戳蓝字"牛晓伟"关注我哦!
用心坚持输出易读、有趣、有深度、高质量、体系化的技术文章,技术文章也可以有温度。
【本文正在参加金石计划附加挑战赛------第三期命题】
前言
四大组件系统 名字的由来:Android中的四大组件Activity、Service、BroadcastReceiver、ContentProvider大家肯定都非常熟悉,而四大组件的启动、运行是需要ActivityManagerService 、App端框架 、PackageManagerService 、zygote进程 这几个主要模块之间的完美配合的。因此我个人给以上四大模块一起所做的事情起了一个高大的名字四大组件系统。
四大组件系统是一个系列的文章,会分别介绍ActivityManagerService、它被划分为哪些模块、它是如何管理四大组件的、如何做进程管理的,App端框架以及框架都有哪些主要模块和类,App进程的启动,Activity、Service、ContentProvider、BroadcastReceiver的启动,ANR (Application not response的缩写)产生原理以及分析过程等内容。
本文摘要
本文采用自述的方式带大家先简单认识ActivityManagerService及它的主要模块划分,App端框架的主要模块和类,ActivityManagerService服务与App端框架之间如何进行交互。 (文中代码基于Android13)
本文大纲
1. ActivityManagerService
大家好,我是ActivityManagerService,关于我在整个Android系统中的地位以及名气,就不需要我过多的介绍了吧,我可是一个非常低调的服务,但是即使我非常低调也还是按捺不住我的名气名扬Android系统。
我这么有名气可不是因为我的颜值而是因为我的内在,我是systemserver进程中最复杂、包含功能最多、最难啃的binder服务之一,并且我管理着Android中鼎鼎有名的四大组件,每个App的四大组件的启动、运行可是都需要经过我的批准。Android系统中都启动了哪些App、启动了哪些四大组件等等这些信息统统都由我来管理。
别看我是一个名人,但是我也有烦恼,那就是我的名字起的非常不好,我的名字没有把我所具有的功能表达出来,看了我的名字还以为我是只管理Activity的,但是我可是管理着四大组件的。
大家大可不必把我想象成超人,能胜任这么多复杂的工作,完全是由我和我的"小伙伴"们一起完成的,先来通过下图来认识下我的主要"小伙伴"
如上图,我的主要"小伙伴"有Activity管理模块 、Service管理模块 、BroadcastReceiver管理模块 、ContentProvider管理模块 、进程管理模块 、App错误管理模块 、App性能分析模块,当然我还有别的不是很重要的模块没有展示出来,那就依次把我的"小伙伴"介绍给大家吧。
1.1 Activity管理模块
Activity管理模块 的主要作用是管理整个Android系统中的所有Activity,比如Activity的启动,Activity的pause,Activity的stop等可都是要经过该模块,而每个被启动的Activity是使用一个ActivityRecord 对象保存的,我把该模块所做的事情全权委托给了ActivityTaskManagerService类,该类也是一个binder服务。关于该模块就暂时介绍到这,后面文章会详细介绍它。
1.2 Service管理模块
Service管理模块 的主要作用是管理所有的Service,Service的启动、销毁等等都是该模块负责,而每个被启动的Service是使用一个ServiceRecord 对象保存的,我同样把该模块所做的事情交给了ActiveServices类,该类可不是一个binder服务。
1.3 BroadcastReceiver管理模块
BroadcastReceiver管理模块 的主要作用是管理所有的BroadcastReceiver,而每个被启动的BroadcastReceiver是使用一个BroadcastRecord 对象保存的,我同样把该模块所做的事情交给了BroadcastQueue,而关于BroadcastQueue的分类可是有好几种分发,会在后面专题中详细介绍。
1.4 ContentProvider管理模块
ContentProvider管理模块 的主要作用是管理所有的ContentProvider,而每个被启动的ContentProvider同样使用一个ContentProviderRecord 对象保存的,我同样把该模块所做的事情交给了ContentProviderHelper类。同样会在后面有专题详细介绍该模块。
1.5 进程管理模块
上面的四个模块所做的事情是管理四大组件,而我除了管理四大组件外我还有非常重要的一个功能就是进程管理 ,而进程管理主要是进程管理模块 在负责,进程管理模块所做的事情主要由ProcessList 和OomAdjuster两个类完成,那就来看下进程管理模块都做了哪些事情吧。
首先在App进程开始孵化(fork)之前,ProcessList会使用ProcessRecord 对象来保存App进程,ProcessList把孵化 (fork)App进程的请求发送给zygote进程,zygote进程孵化成功App进程后,ProcessList会收到这个消息,进而把孵化成功的App进程的pid (进程id)等信息保存到ProcessRecord对象中。因此ProcessList中保存了所有的App进程。
进程管理模块所做的事情可不是仅仅把App进程保存起来这么简单,不知道大家是否记得lmkd 进程 (不记得可以看lmkd进程杀手这篇文章),lmkd进程的主要作用是根据内存的使用情况来杀掉分数最高的进程 ,而具有运行Java/Kotlin代码的进程的分数是由OomAdjuster来完成的,OomAdjuster会对所有的进程都计算出一个分数 (oom_score),比如当前正在显示的Activity对应的App的分数值是0,并且把分数、进程id、uid这些信息发送给lmkd进程。
OomAdjuster在计算每个进程的分数时,也同时会计算出每个进程对应的进程状态 (procState),比如正在显示的Activity对应的进程状态值是PROCESS_STATE_TOP (它的值是2),和进程分数一样,进程状态值越大越容易被杀掉以及分配的资源越少。
当然除了依靠lmkd进程杀进程外,OomAdjuster也会在合适的时机根据一些条件来把进程状态为PROCESS_STATE_CACHED_EMPTY或者PROCESS_STATE_CACHED_ACTIVITY或者PROCESS_STATE_CACHED_ACTIVITY_CLIENT的进程杀掉,这个杀进程的过程可是不需要lmkd进程参与的。
对于一些处于后台又没有BroadcastReceiver或者Service或者ContentProvider运行的进程,该模块会选择把它冻结 或者杀死,负责冻结功能的类是CachedAppOptimizer。
这里只是先简单带大家认识进程管理模块,同样也会在后面专题中着重介绍它。
1.6 App错误管理模块
App进程同生物的生命一样也会存在生、死,当App进程死掉的时候,不管是由于崩溃或者ANR (Application not response)或者自身原因的死掉,都需要App错误管理模块 来处理App进程的"后世",若App死掉该模块会把App进程当时死掉的堆栈状态保存下来,如果是由于ANR导致的死亡,也会把ANR的各种信息保存下来。负责该模块的主要类是AppErrors。
App进程在死掉的时候,也会把App进程死掉的相关重要信息保存在文件中,而做这个工作的类是AppExitInfoTracker,当然除了做这些工作之外,还有其他的工作内容就暂时不细说了。
1.7 App性能分析模块
App性能分析模块 的主要作用是可以统计每个App进程所暂用的CPU资源、内存的使用情况等数据,负责该模块的主要类是AppProfiler,关于该模块会在后面专题详细介绍。
1.8 小结
通过上面的介绍大家应该对我ActivityManagerService 和我的主要模块有了一个清晰的了解,当然对以上模块的介绍只是先简单带大家认识它们,后面会有各自专题详细的介绍它们。大家可以把我理解为四大组件系统的服务端,四大组件系统要想正常运转是离不开App端的,那就来看下App端的框架。
2. App端框架
大家好,我是App端框架,我存在于每个App进程内,我搭建好了一套框架,App开发者只需要实现自己的四大组件和Application并且把它们配置在AndroidManifest.xml文件中即可,至于四大组件和Application这些对象何时被创建,以及它们的生命周期方法何时被调用,开发者统统都不需要关心,开发者只需要做的就是在各自的生命周期方法中加入自己的业务逻辑即可。看到没有我可是给广大开发者带来了很大的便利的,如下图展示App端框架的一个大体运行过程:
结合上图我先简单介绍下App端框架的运行过程:
- 凡是从ActivityManagerService过来的数据,都需要经过ApplicationThread类,这本身是一个binder通信的过程。而大部分数据会通过Handler post到UI线程去执行,ActivityThread会把各种数据进行分发,比如是启动Activity的还是启动Service的等等。
- 当App进程被创建后,ActivityManagerService会把当前App的各种重要信息比如包名、Apk版本信息、Apk文件路径、so库文件路径、共享库文件路径等等这些数据传递给App进程,LoadedApk会把Apk文件路径、so库文件路径、共享库文件路径这些数据交给类加载器,类加载器就可以加载当前Apk中的各种类了。
- 在启动一个Activity的时候,ActivityManagerService会把Activity的信息如Activity的类名通过binder通信传递给ActivityThread,而ActivityThread会根据要启动的Activity的类名通过反射,初始化一个对应Activity的实例,进而会调用相应Activity的onCreate、onResume这些生命周期方法。
上面只是简单的介绍了App端框架的大体运行过程,像Application、Service、ContentProvider、BroadcastReceiver的启动和对应生命周期方法的运行也和Activity是一致的。
App端框架可以让App开发者关注自己的业务逻辑即可,至于四大组件及Application的何时被创建、何时调用哪个生命周期方法,开发者都不需要关心。而像四大组件创建及生命周期方法被调用的这些命令完全是由ActivityManagerService通过binder通信发送给App进程的。
3. 总结
本篇是四大组件系统 系列的开篇,开篇主要是带大家认识了ActivityManagerService 和App端框架,四大组件的创建及生命周期方法的调用都是离不开ActivityManagerService和App端框架的完美配合,ActivityManagerService是作为server,而App端框架是存在于App进程作为client端。
后面的系列文章会详细的介绍ActivityManagerService、App端框架、App进程的创建过程、四大组件的启动过程、ANR等内容,欢迎大家收看。