AMS和PMS过程

当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的具体内容

解析<activity>过程中也会解析其子标签 如<intent-filter>

这个内容会放到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方法


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容