AMS和PMS过程

102 阅读3分钟

当activity跳转到另一个app的activity时,或者应用内activity跳转时所发生的事情大致如下

  1. 遍历data/app下所有的app
  2. 解压apk
  3. dom解析AndroidManifest.xml 得到activity标签等
  4. 得到入口activity的全类名 或其他activity的全类名 进行反射构建对象
  5. 得到activity的实例

这个过程非常耗时 所以将他给PMS,和AMS管理

PMS管理 (1)(2)(3)三个步骤 AMS管理(4,5)两个步骤

(1-3)发生在开机的时候 只需要运行一次

(4-5)需要的时候

PMS:作用 包管理,包解析,结果缓存,提供查询接口

Android 7.0 PackageManagerService源码地址

android-7.0.0_r1\frameworks\base\services\core\java\com\android\server\pm

app的安装路径 mAppInstallDir 找到这个作为入口来看 如何对这个里面的文件进行操作

mAppInstallDir =new File(dataDir, "app");

找到 scanDirTracedLI(mAppInstallDir)方法中使用了该路径

上面的PackageParser 是一个重要的类.主要用来解析Package

android.content.pm.PackageParser.java

之后就调用PackageParser.java中的内容

这里的packageFile有可能是单独的base.apk文件 也有可能是一个APKs的文件夹

Parse the package at the given location. Automatically detects if the package is a monolithic style (single APK file) or cluster style (directory of APKs).

我这里简单的看一下单个目录 的形式

进入parseBaseApk()方法看一下

这里的ANDROID_MANIFEST_FILENAME 就是对应的AndroidManifest.xml 文件

这里会开始解析AndroidManifest.xml 获取到manifest标签中的versionCode versionName等信息

parseBaseApkCommon()方法中 有对应解析application标签的内容.

parseBaseApplication()方法中可以得到application标签中的内容

eg :theme,descriptionRes,taskAffinity等等

同时 application内部的标签 如 activity也在这里解析 parseActivity()方法

同時

将解析出来的结果加入了owner.activies

可以看到这里的是四大组件解析出的内容 以及其他AnroridManifest.xml中解析的内容

需要注意的是 这里的Activity不是android.app.Activity 而是PackageParser的内部类相当于一个ActivityBean存放activity的相关信息

Provider,Service,Permission 也是一样的 都是PackageParser的内部类

private ActivityparseActivity(Package owner, Resources res,

    XmlResourceParser parser, int flags, String[] outError,
​
    boolean receiver, boolean hardwareAccelerated)

throws XmlPullParserException, IOException { 方法就是具体解析activity/receiver的具体内容

解析过程中也会解析其子标签 如

这个内容会放到ActivityIntentInfo

最终将结果缓存到mPackages中 供以后使用

final ArrayMap <String,PackageParser.Package>mPackages = new ArrayMap();

以上是PMS的相关内容

下面看一下AMS(以API28为例)

AMS 是由Activity的启动开始 这里由启动Activity开始

startActivity 最终调用的是Activity类中的startActivity()方法

startActivity 中调用 startActivityForResult()

startActivityForResult 中 调用 Instrumentation

mInstrumentation.execStartActivity(

this, mMainThread.getApplicationThread(), mToken, this,

intent, requestCode, options);

Instrumentation.java 中的 execStartActivity()方法中重要 内容如下 :

int result = ActivityManager.getService()

.startActivity(whoThread, who.getBasePackageName(), intent,

        intent.resolveTypeIfNeeded(who.getContentResolver()),
​
        token, target !=null ? target.mEmbeddedID :null,
​
        requestCode, 0, null, options);

其中 ActivityManager.getService()

singleTon是一个单例模式 它的get() 对象返回的就是 它的实现类中对应的create()方法返回的内容.

所以这里的getDefault()返回的就是

final IActivityManager am = IActivityManager.Stub.asInterface(b);

这里进行了进程间通信 .这里由activty转到了AMS

也就是说调用了ActivityManagerService中的startActivity()

调用几个重载方法后 mActivityStartController.obtainStarter(intent, "startActivityAsUser") .. .execute()

其中注意这里 setMayWait(userId)将 myWait设置为true了

obtainStarter() 返回的是ActivityStarter

也就是 后面调用ActivityStarter的 execute()方法

startActivityMayWait()方法中 重点为

ActivityStackSupervisor.java 中 resolveIntent()中涉及到了 PackageManagerService

这里的 final ActivityManagerService mService

所以调用的是ActivityManagerService.java中的 getPackageManagerInternalLocked()方法

PackageManagerInternal 是PackageManagerService的内部类 其实现类为PackageManagerInternalImpl

private class PackageManagerInternalImpl extends PackageManagerInternal {

也就是调用这里的resolveIntent方法

这里返回的ResolveInfo就包括 应用中的一下信息等。

这样就AMS就由PMS中获取了应用的相关信息.

回到ActivtyStarter的startActivityMayWait()方法

ResolveInfo rInfo =mSupervisor.resolveIntent(intent, resolvedType, userId,

    0 /* matchFlags */,
​
            computeResolveFilterUid(

callingUid, realCallingUid, mRequest.filterCallingUid));

通过的该代码获取到rInfo 后,

ActivityInfo aInfo =mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

得到 aInfo

这里开始启动activity 连续几个重载的startActivity方法