当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方法