在上篇Zygote进程探索我们说到zygote进程fork出了SystemServer进程,SystemServer进程又开启了AMS、PMS等重要服务。今天我们就来探索AMS的世界。
前面说到是SystemServer来启动的AMS,那么我们就来看看SystemServer的源码。这个类的路径在frameworks/base/services/java/com/android/server/SystemServer.java,找到源码可以发现是个Java类,那么我们就看看它的main方法吧。

我们可以看到在main方法中只有一行代码,只调用了run方法。跟着代码走吧。
这个方法的源码很长,我们只看其中的关键部分。

我们在run()方法的后半部分可以找到上述一段代码。就是用来启动各种服务。去startBootstrapServices中浅看一下。
我们可以在其中找到关键的代码。

我们可以看到ActivityManagerService调用了lifecycle的startService方法。我们再看看Lifecycle是个什么样子吧。

大家可以发现Lifecycle其实是AMS的内部类,在构造函数中实例化了我们需要的AMS实例。那么谁又调用了Lifecycle的构造方法呢?我们接着往下看,我们知道,最终调用了Lifecycle.startService(),而我们可以看到在Lifecycle.startService方法中其实是调用了SystemServiceManager.startService()方法,并把Lifecycle的class传入进去了。那么在SystemServiceManager.startService()里是不是会调用到Lifecycle的构造方法呢。
我们来瞧瞧。

我们往下可以看到通过反射调用到Lifecycle的构造方法并将Lifecycle实例返回给上层调用。返回Lifecycle实例之后,会调用getService()方法获取到已经实例化的AMS。
有人会问那么实例化,也没有看见服务启动啊。我们仔细看在SystemService.startService()中在返回service之前,有一个startService()方法,我们去看看。

我们返回的是Lifecycle实例,被添加到容器中,然后启动。可能我们都忽略一个细节,那就是Lifecycle这个内部类其实是继承了SystemService的并且重写了onStart方法,而在Lifecycle重写的方法中,调用了AMS的start方法。
到这里大家对于整个AMS的启动有没有了解呢。
上面分析过了AMS启动过程,那么我们现在还不知道AMS在Android系统中起什么作用。下面就一起来看看吧。
假设系统中没有AMS和PMS,我们从一个activity跳转到另一个activity的话,就需要自己去解压缩apk文件,然后解析AndroidManifest.xml解析出activity,再实例化再去跳转。每一次跳转都会去做这样的操作,非常耗时。所以我们就需要我们AMS和PMS出场了。
PMS全称是PackageManagerService,一看就是管理包相关的。大家打开Android模拟器的存储目录会发现一个/data/app目录,目录里面是我们手机上应用的包名,PMS就会去扫描这个目录。我们再去SystemServer中看看PMS的逻辑吧。

我们可以看到直接调用了PMS的main方法。既然是扫描/data/app/目录,那我们就找到相关代码阅读一下。
PMS的main方法里面代码很多,但是肯定会在里面实例化一个PMS实例,我们就依据这个来看看吧。

可以看到PMS没有那么多花里胡哨的实例化,直接new了一个PMS对象。看样子扫描目录应该就在构造方法里面。

果然在构造方法去访问了/data/app目录,Environment.getDataDirectory()返回的就是/data/字符串。既然拿到了文件实例,那么肯定是需要使用的,只需要看看这个变量在哪里使用就好了。

查找时会发现,这段代码其实也在构造方法中。我们去看看这个方法里都做了啥吧。

可以看到开始对目录下的APK文件开始扫描了,并且使用一个线程池来开始扫描任务。因为这里是最新源码(Android 12)所以大家可以看到的是使用线程池来开启任务。在之前Android 7 的时候在主线程中开启扫描任务。有兴趣的同学可以去看看Android 7 的源码对比来看看。我们再追踪到submit方法中。

在submit方法中最终会调用到parsePackage()中,这个mPackageParser是一个 PackageParser2对象,最终会走到PackageParser2.parsePackage()中。我们接下来去看看吧。

我们可以看到在核心代码中解析工作还是交给了一个parsingUtils.parsePackage最后会得到一个ParsingPackage。所有的解析操作都在ParsingPackageUtils这个类中完成,我们之后再分析,当然解析主要是解析AndroidManifest.xml,会把里面所有涉及到的结点都会缓存下来。
可以看看ParsingPackage里面的相关代码。
public interface ParsingPackage extends ParsingPackageRead {
ParsingPackage addActivity(ParsedActivity parsedActivity);
ParsingPackage addAdoptPermission(String adoptPermission);
ParsingPackage addConfigPreference(ConfigurationInfo configPreference);
ParsingPackage addFeatureGroup(FeatureGroupInfo featureGroup);
ParsingPackage addImplicitPermission(String permission);
ParsingPackage addInstrumentation(ParsedInstrumentation instrumentation);
ParsingPackage addKeySet(String keySetName, PublicKey publicKey);
ParsingPackage addLibraryName(String libraryName);
ParsingPackage addOriginalPackage(String originalPackage);
ParsingPackage addOverlayable(String overlayableName, String actorName);
ParsingPackage addPermission(ParsedPermission permission);
// ...省略部分代码
}
是不是可以看到好多熟悉的东西,在解析之后就会存起来,方便AMS调用。我们还可以看看实现类。
public class ParsingPackageImpl implements ParsingPackage, Parcelable {
private static final String TAG = "PackageImpl";
@NonNull
@DataClass.ParcelWith(ForInternedStringList.class)
protected List<String> protectedBroadcasts = emptyList();
@NonNull
protected List<ParsedActivity> activities = emptyList();
@NonNull
protected List<ParsedActivity> receivers = emptyList();
@NonNull
protected List<ParsedService> services = emptyList();
@NonNull
protected List<ParsedProvider> providers = emptyList();
@NonNull
private List<ParsedAttribution> attributions = emptyList();
}
看到熟悉的四大组件没,其中的ParsedActivity、ParsedService等大家可以理解成一个bean类用来存放解析出来的数据。
在PMS是用final WatchedArrayMap<String, AndroidPackage> mPackages = new WatchedArrayMap<>() 这样的一个map存起来的。key是包名,值就是上面所存储的 ParsingPackage。
这样整个PMS的工作也就完成了,解压缩apk,解析xml文件。
上面分析了PMS的逻辑,下面来看看AMS都做了什么吧。
AMS是用来管理activity的,想要了解我们就从最简单的跳转开始吧,从startActivity()开始吧。
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)
&& mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY)) {
if (TextUtils.equals(getPackageName(),
intent.resolveActivity(getPackageManager()).getPackageName())) {
// Apply Autofill restore mechanism on the started activity by startActivity()
final IBinder token =
mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);
// Remove restore ability from current activity
mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);
mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY);
// Put restore token
intent.putExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN, token);
intent.putExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY, true);
}
}
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
我们在外部调用startActivity方法时,我们最后就会调用到上述代码。
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
//...省略代码
}
最终会走到mInstrumentation.execStartActivity()中。这里也没有涉及到AMS,我们接着往下看。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
//....省略代码
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
int result = ActivityTaskManager.getService().startActivity(whoThread,
who.getOpPackageName(), who.getAttributionTag(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()), token,
target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
这里开始就有点AMS的味道了,那么这个getService()获取的到底是不是AMS呢,我们接着探索。
/** @hide */
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
看到这里我们可能发现AMS还没有出现,代替的是ActivityTaskManager,没错,Android10 之后,AMS就把管理Activity的工作交给了ActivityTaskManager。
我们先来分析分析上述代码吧。getService返回的是IActivityTaskManagerSingleton.get(),具体我们看看Singleton这个类就好了。
public abstract class Singleton<T> {
@UnsupportedAppUsage
public Singleton() {
}
@UnsupportedAppUsage
private T mInstance;
protected abstract T create();
@UnsupportedAppUsage
public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}
不知道大家看清楚这个单例模式没有,实例不是自己new的,是通过create方法返回的。那么之前的代码就非常好理解了,get()方法其实拿到的是create()的返回值,就是返回了一个Binder对象并转化IActivityTaskManager,也就是说其实我们app内部跳转Activity是一个跨进程通信。这里就是从APP进程到AMS的进程里面去了。
我们可以接着往下看Stub的实现类ActivityTaskManagerService。我们找到如下代码。
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
最终会走到startActivityAsUser。
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setUserId(userId)
.execute();
}
不用看上面的一大堆代码,我们只看最后的方法execute(),上面一大堆设置变量最后也会到execute()中执行。
int execute() {
try {
// Refuse possible leaked file descriptors
if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
final LaunchingState launchingState;
synchronized (mService.mGlobalLock) {
final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
final int callingUid = mRequest.realCallingUid == Request.DEFAULT_REAL_CALLING_UID
? Binder.getCallingUid() : mRequest.realCallingUid;
launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
mRequest.intent, caller, callingUid);
}
// If the caller hasn't already resolved the activity, we're willing
// to do so here. If the caller is already holding the WM lock here,
// and we need to check dynamic Uri permissions, then we're forced
// to assume those permissions are denied to avoid deadlocking.
if (mRequest.activityInfo == null) {
mRequest.resolveActivity(mSupervisor);
}
}
}
我们可以看代码中的注释哈。会在resolveActivity中处理相关逻辑。
void resolveActivity(ActivityTaskSupervisor supervisor) {
//....省略部分代码
resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,
0 /* matchFlags */,
computeResolveFilterUid(callingUid, realCallingUid, filterCallingUid));
}
最后会在resolveIntent中拿到我们所需要的东西的。
ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags,
int filterCallingUid) {
//...省略部分代码
final long token = Binder.clearCallingIdentity();
try {
return mService.getPackageManagerInternalLocked().resolveIntent(
intent, resolvedType, modifiedFlags, privateResolveFlags, userId, true,
filterCallingUid);
} finally {
Binder.restoreCallingIdentity(token);
}
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
其中mService是ActivityTaskManagerService。看看返回的对象是什么吧。
PackageManagerInternal getPackageManagerInternalLocked() {
if (mPmInternal == null) {
mPmInternal = LocalServices.getService(PackageManagerInternal.class);
}
return mPmInternal;
}
看到这里AMS是不是就应该和PMS产生了联系呢,我们再仔细看看。看看PackageManagerInternal能不能在PMS中找到吧。
private class PackageManagerInternalImpl extends PackageManagerInternal {
@Override
public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
int callingUid) {
return PackageManagerService.this.getInstalledApplicationsListInternal(flags, userId,
callingUid);
}
@Override
public boolean isPlatformSigned(String packageName) {
PackageSetting packageSetting = mSettings.getPackageLPr(packageName);
if (packageSetting == null) {
return false;
}
AndroidPackage pkg = packageSetting.pkg;
if (pkg == null) {
// May happen if package in on a removable sd card
return false;
}
return pkg.getSigningDetails().hasAncestorOrSelf(mPlatformPackage.getSigningDetails())
|| mPlatformPackage.getSigningDetails().checkCapability(pkg.getSigningDetails(),
PackageParser.SigningDetails.CertCapabilities.PERMISSION);
}
//...省略部分代码
}
我们可以在PMS中找到一个实现类,其实我们最终返回的对象就是PackageManagerInternalImpl。我们可以看其中部分的代码实现。因为是PMS的内部类,所以直接调用PMS的对象访问PMS自己的方法再通过内部类提供给外部。我们再回过头看看ResloveInfo。
public class ResolveInfo implements Parcelable {
private static final String TAG = "ResolveInfo";
private static final String INTENT_FORWARDER_ACTIVITY =
"com.android.internal.app.IntentForwarderActivity";
/**
* The activity or broadcast receiver that corresponds to this resolution
* match, if this resolution is for an activity or broadcast receiver.
* Exactly one of {@link #activityInfo}, {@link #serviceInfo}, or
* {@link #providerInfo} will be non-null.
*/
public ActivityInfo activityInfo;
/**
* The service that corresponds to this resolution match, if this resolution
* is for a service. Exactly one of {@link #activityInfo},
* {@link #serviceInfo}, or {@link #providerInfo} will be non-null.
*/
public ServiceInfo serviceInfo;
/**
* The provider that corresponds to this resolution match, if this
* resolution is for a provider. Exactly one of {@link #activityInfo},
* {@link #serviceInfo}, or {@link #providerInfo} will be non-null.
*/
public ProviderInfo providerInfo;
/**
* An auxiliary response that may modify the resolved information. This is
* only set under certain circumstances; such as when resolving instant apps
* or components defined in un-installed splits.
* @hide
*/
public AuxiliaryResolveInfo auxiliaryInfo;
/**
* Whether or not an instant app is available for the resolved intent.
*/
public boolean isInstantAppAvailable;
/**
* The IntentFilter that was matched for this ResolveInfo.
*/
public IntentFilter filter;
//...省略部分代码
}
在ResloveInfo中是存储了关于四大组件的所有信息了。我们通过PMS之前解析的东西都放在ResolveInfo中,我们就可以在ResolveInfo中拿到我们所需要的所有东西。
拿到我们想要的东西之后,就回到最开始的地方execute方法。execute方法中会调用resolveActivity方法,就是在这里我们就去和PMS通信了。我们现在就从这里开始吧。
// Collect information about the target of the Intent.
activityInfo = supervisor.resolveActivity(intent, resolveInfo, startFlags,
profilerInfo);
这里拿到activityInfo之后,我们就接着回去看execute方法。这里activityInfo是一个全局变量,存放在一个Request 的内部类中。我们再看看execute方法中其他的代码吧。
if (mRequest.activityInfo == null) {
mRequest.resolveActivity(mSupervisor);
}
//...省略部分代码
res = executeRequest(mRequest);
在我们拿到信息之后就会去执行executeRequest方法,在这里面去接着执行我们的启动流程。
之后就是看源码的的流程了就不再多说了。
我们已经了解AMS、PMS各自逻辑以及相互的联系了,这也是本次文章的目的。