ActivityManagerService
前语
其实早在几年前,我就有一个疑问。
- 为什么咱们的逻辑代码写在Activity中,在App发动后就会履行到它。
- 为什么第三方库的初始化要写在Application中,而它为什么履行次序比Activity还要靠前。
假如您想搞清楚这些原因,那么本文或许会给你提供少许协助。文章很长(尽管这不是我的初衷),建议感兴趣的同学,坚持读完。
文章中会呈现许多类名和办法名,它们仅仅是便利回忆用的。咱们不必去强行记住,只需记住一些要害点即可。回头把本文当作一个字典,有忘掉的点再重新看一下就行。
别的:因为本文太长。因此只适合一些,对App发动流程不太了解的同学。假如是非常了解的同学,能够直接略过本文。
本文将会经过Launcher的发动,解说AMS的创立进程,进程的割裂流程,以及咱们是怎么履行到Activity的onCreate办法的。
老规矩,阅读文章之前,让咱们先看一下这几个问题:
- AMS是怎么创立的,它运转在哪个进程之中。
- ATMS和AMS的功能是什么差异又是什么。
- ServiceManager的效果是什么。
- App进程怎么割裂来的。
- 为什么咱们App会执ActivityThread的main办法。
- 咱们是怎么履行Activity的onCreate办法的。
期望您能够在看完文章之后,回答出上面的问题。假如您觉得文章对您有协助的话,能够点个赞,加个重视,便利回头检查本文。
下面咱们正式开端。
1. AMS怎么发动
咱们先来聊一下AMS的创立进程。上一篇文章中现已讲了,假如看过上篇文章的能够直接略过本节。假如还没看上篇文章,能够经过这节简略了解下。
1.1 SystyemServer中的AMS
咱们知道,在Android发动流程中,Zygote进程fork出了SystemServer进程。而SystemServer进程中先后敞开了几十个服务,而这其中就包含了AMS进程和ATMS进程。详细代码如下:
public final class SystemServer {
/**
* 敞开引导服务
*/
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
// Activity manager runs the show.
// 创立ATMS,经过SystemServiceManager调用AMTS的start办法,并增加到ServiceManager中
ActivityTaskManagerService atm = mSystemServiceManager.startService(
ActivityTaskManagerService.Lifecycle.class).getService();
// 创立AMS。并持有ATMS引证
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
mSystemServiceManager, atm);
// 让AMS 持有 SystemServer中的SSM的引证
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
// 让AMS 持有 SystemServer中的INSTALLER的引证
mActivityManagerService.setInstaller(installer);
// Set up the Application instance for the system process and get started.
mActivityManagerService.setSystemProcess();
}
}
1.2 AMS和ATMS
AMS的功能是办理四大组件。经过获取进程的ApplicationThread目标,然后跨进程告知App进程创立Application和Activity目标。 可是从Android10.0.之后。或许是Google开发人员,觉得AMS的功能过于冗杂,违反了单一责任,所以又建了一个ActivityTaskManagerService(ATMS)用来办理Activity。减轻AMS担负。或许为了坚持接口一致性,又让AMS持有ATMS的引证。
这操作像不像公司中的你,一个人肩负重任,为了减轻你的担负,给你找了个小老弟把你俩分成一组,他会分担你的部分工作。一起这个小老弟的工作要向你陈述。而你要把你俩的工作成果对你的上层陈述。
1.3 ServiceManager服务大管家
这儿要多讲一个类,叫做ServiceManager。这是由init进程发动而来的一个看护进程,它运转在用户空间。因为他的特殊效果是,所有binder服务都要在这个ServiceManager进程进行注册,所以它又被称作Binder服务大管家。
说他是大管家是因为,咱们都知道,为了App进程的安全性,所以进程与进程之间正常是无法相互拜访的。假如想要相互拜访,就要经过跨进程通讯,在Android中最常见的跨进程通讯便是Binder、Socket、共享内存等。但出于功能和安全性考虑,Binder成了Android官方推出的跨进程通讯机制。
而因为进程和进程之间都相互不认识,所以就需求个介绍人,这个介绍人便是ServiceManager。有点相似于咱们找工作,会把咱们的个人信息投递到第三方渠道,而公司招聘也会去第三方渠道。这儿的ServiceManager就相当于第三方渠道。
咱们的AMS,会经过ServiceManager.addService(Context.ACTIVITY_SERVICE, this); 告知ServiceManager。假如有人想要找我,就只需求报出我的艺名Context.ACTIVITY_SERVICE 就行。
而别的进程要是找AMS,就要找ServiceManager,调用它的getService(Context.ACTIVITY_SERVICE) 办法。告知ServiceManager,我要找叫做Context.ACTIVITY_SERVICE的小姐姐。ServiceManager就会将AMS的目标回来给那个进程。然后完成跨进程通讯。
public final class ServiceManager {
@UnsupportedAppUsage
// 留意,这儿的service都是IBinder目标,AMS,ATMS等都是IBinder目标。
public static void addService(String name, IBinder service) {
addService(name, service, false, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
}
@UnsupportedAppUsage
public static void addService(String name, IBinder service, boolean allowIsolated) {
addService(name, service, allowIsolated, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
}
/**
* 将service对像(IBinder目标),以name的称号存放到ServiceManager进程中
*/
@UnsupportedAppUsage
public static void addService(String name, IBinder service, boolean allowIsolated,
int dumpPriority) {
try {
getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
/**
* 获取ServiceManager进程Binder目标
*/
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
sServiceManager = SereManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
/**
* 经过称号回来IBinder目标
*/
@UnsupportedAppUsage
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return Binder.allowBlocking(rawGetService(name));
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
/**
* This is only intended to be called when the process is first being brought
* up and bound by the activity manager. There is only one thread in the process
* at that time, so no locking is done.
*
* @param cache the cache of service references
* @hide
*/
public static void initServiceCache(Map<String, IBinder> cache) {
if (sCache.size() != 0) {
throw new IllegalStateException("setServiceCache may only be called once");
}
sCache.putAll(cache);
}
}
1.4 AMS设置体系相关服务
如下代码所示,设置体系常用进程至ServiceManger中。因为咱们的AMS本身便是个继承自Binder的类。所以能够直接增加进ServiceManager。而且称号为Context.ACTIVITY_SERVICE。这儿还有一些其他的Binder目标被增加到ServiceManager中,详细看代码即可。
别的ATMS也是经过相似的办法被加入到ServiceManager中。详细能够经过: ActivityTaskManagerService atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); 检查到相关代码。
public class ActivityManagerService extends IActivityManager.Stub{
public void setSystemProcess() {
try {
// 将AMS增加到ServiceManager中,取名为Context.ACTIVITY_SERVICE
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
// 增加MemBinder
ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_HIGH);
// 增加GraphicsBinder
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
// 增加DbBinder
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
// 增加CpuBinder
ServiceManager.addService("cpuinfo", new CpuBinder(this),
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
}
// 增加PermissionController
ServiceManager.addService("permission", new PermissionController(this));
// 增加ProcessInfoService
ServiceManager.addService("processinfo", new ProcessInfoService(this));
// 增加CacheBinder
ServiceManager.addService("cacheinfo", new CacheBinder(this));
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
synchronized (this) {
ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
false,
0,
new HostingRecord("system"));
app.setPersistent(true);
app.pid = MY_PID;
app.getWindowProcessController().setPid(MY_PID);
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
addPidLocked(app);
mProcessList.updateLruProcessLocked(app, false, null);
updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e);
}
}
}
1.5 留意事项
这儿需求留意几点:
- AMS和ATMS等都不是独自的进程,而是运转在SystemServer进程中的。
- ServiceManager增加的目标是IBinder目标,是用来跨进程通讯的。
- AMS和ATMS能够经过ServiceManager获取。然后完成APP进程和SystemServer之间的通讯。
2. AMS发动Launcher之旅
发动Android体系终究一个环节是:发动一个Launcher的App。假如有不知道的小伙伴能够检查下这篇文章 问个问题,请描述下Android体系的发动流程。
这儿的发动调用进程过于复杂,个人认为记这个调用流程没有任何意义。只需记住一些要害办法即可。 我尽量写的能让各位记住。或许咱们只记住要害办法以及终究成果亦可。
2.1 systemReady()
在SystemServer进程的startOtherServices中。经过AMS的systemReady办法。开端创立Launcher进程之旅。详细代码如下所示:
public final class SystemServer {
/**
* 敞开其他服务
*/
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
// 创立IMS
inputManager = new InputManagerService(context);
// 创立WMS
wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
// IMS 增加到 ServiceManager
ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false,
DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO);
// WMS 增加到 ServiceManager
ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
// 发动systemReady,开端发动launcher之旅
mActivityManagerService.systemReady(() -> {}
}
}
2.2 创立Launcher进程
下图是SystemServer经过AMS创立Luancher进程的要害办法的时序图。
这儿咱们只记住要害办法即可。此处的时序图只是便利咱们了解和查询的。
要留意,这个时序图的效果只是告知咱们,SystemServer进程中怎么经过Socket和Zygote进程进行通讯。然后割裂出一个App进程。
sequenceDiagram
SystemServer->>ActivityManagerService: startOtherServices
ActivityManagerService->>ActivityTaskManagerService:systemReady
ActivityTaskManagerService->>RootWindowContainer:resumeTopActivities
RootWindowContainer->>ActivityStartController:省掉......
ActivityStartController->>ActivityStarter:execute
ActivityStarter->>ActivityStack:省掉......
ActivityStack->>ActivityStackSupervisor:startSpecificActivity(冷发动和热发动)
ActivityStackSupervisor->>ActivityTaskManagerService:startProcessAsync
ActivityTaskManagerService->>ZygoteProcess:省掉......
ZygoteProcess->>ZygoteProcess:startViaZygote
ZygoteProcess->>ZygoteProcess:zygoteSendArgsAndGetResult:发送参数给zygote创立子进程一起回来子进程的相关成果
ZygoteProcess->>ZygoteProcess:attemptUsapSendArgsAndGetResult:将参数经过socket发送给zygote进程,告知zygote割裂出一个子进程,并回来子进程pid。
2.2 热发动?or 冷发动?
发动App的要害办法之一便是ActivityStackSupervisor的startSpecificActivity办法。这儿存在别的两个极其重要的办法。一个是realStartActivityLocked,另一个是startProcessAsync。
startSpecificActivity办法中会判别进程是否存在,假如发动的APP进程现已存在,则调用realStartActivityLocked。
假如不存在,则调用ATMS的startProcessAsync() 办法,先发动进程。
进程存在的发动办法便是热发动:realStartActivityLocked();
进程不存在的发动办法便是冷发动:startProcessAsync();
因为Launcher还没有创立,所以此处履行的是冷发动。而realStartActivityLocked后边将会进行解说。
public class ActivityStackSupervisor{
final ActivityTaskManagerService mService;
// 经过热发动或许冷发动,发动APP
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
// 进程存在,热发动。在现已存在的进程中履行后续代码
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
knownToBeDead = true;
}
final boolean isTop = andResume && r.isTopRunningActivity();
// 进程不存在,冷发动。创立新的进程
// 此处的mService是ATMS
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
}
2.3 ATMS预备创立新进程
经过ATMS发动进程,终究会调用ZygoteProcess类。该类会填写新进程的详细参数。
在startViaZygote办法中,processClass为要发动main办法的类名,niceName是fork出的新进程的进程名。
经过Socket传递给Zygote进程,一起将Zygote进程中创立的子进程的pid回来给该进程中。经过回来进程的pid,来区分是Zygote进程还是子进程。
详细看下面代码中的注释。没有幻想中的复杂。
public class ZygoteProcess {
/**
* Starts a new process via the zygote mechanism.
*
* @param processClass Class name whose static main() to run
* @param niceName 'nice' process name to appear in ps
* @return An object that describes the result of the attempt to start the process.
* @throws ZygoteStartFailedEx if process start failed for any reason
*/
private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
@Nullable final String niceName,
final int uid, final int gid,
@Nullable final int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
boolean startChildZygote,
@Nullable String packageName,
int zygotePolicyFlags,
boolean isTopApp,
@Nullable long[] disabledCompatChanges,
@Nullable Map<String, Pair<String, Long>>
pkgDataInfoMap,
@Nullable Map<String, Pair<String, Long>>
whitelistedDataInfoMap,
boolean bindMountAppsData,
boolean bindMountAppStorageDirs,
@Nullable String[] extraArgs)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<>();
// --runtime-args, --setuid=, --setgid=,
// and --setgroups= must go first
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
argsForZygote.add("--runtime-flags=" + runtimeFlags);
if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
argsForZygote.add("--mount-external-default");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
argsForZygote.add("--mount-external-read");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
argsForZygote.add("--mount-external-write");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_FULL) {
argsForZygote.add("--mount-external-full");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER) {
argsForZygote.add("--mount-external-installer");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_LEGACY) {
argsForZygote.add("--mount-external-legacy");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
argsForZygote.add("--mount-external-pass-through");
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {
argsForZygote.add("--mount-external-android-writable");
}
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
if (niceName != null) {
argsForZygote.add("--nice-name=" + niceName);
}
if (seInfo != null) {
argsForZygote.add("--seinfo=" + seInfo);
}
if (instructionSet != null) {
argsForZygote.add("--instruction-set=" + instructionSet);
}
if (appDataDir != null) {
argsForZygote.add("--app-data-dir=" + appDataDir);
}
if (invokeWith != null) {
argsForZygote.add("--invoke-with");
argsForZygote.add(invokeWith);
}
if (startChildZygote) {
argsForZygote.add("--start-child-zygote");
}
if (packageName != null) {
argsForZygote.add("--package-name=" + packageName);
}
if (isTopApp) {
argsForZygote.add(Zygote.START_AS_TOP_APP_ARG);
}
if (bindMountAppStorageDirs) {
argsForZygote.add(Zygote.BIND_MOUNT_APP_STORAGE_DIRS);
}
if (bindMountAppsData) {
argsForZygote.add(Zygote.BIND_MOUNT_APP_DATA_DIRS);
}
// 将会用行processClass这个类的main办法
argsForZygote.add(processClass);
if (extraArgs != null) {
Collections.addAll(argsForZygote, extraArgs);
}
synchronized(mLock) {
// openZygoteSocketIfNeeded 敞开socket,预备socket通讯
// argsForZygote便是传递给Zygote进程,要发动的新进程的相关参数
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
zygotePolicyFlags,
argsForZygote);
}
}
/**
* Sends an argument list to the zygote process, which starts a new child
* and returns the child's pid.
*/
private Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
throws ZygoteStartFailedEx {
// 将新进程的相关参数args,写入到msgStr中
String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";
// 传递 msgStr
return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
}
// socket 传递数据。回来新进程相关成果
private Process.ProcessStartResult attemptUsapSendArgsAndGetResult(
ZygoteState zygoteState, String msgStr)
throws ZygoteStartFailedEx, IOException {
try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) {
final BufferedWriter usapWriter =
new BufferedWriter(
new OutputStreamWriter(usapSessionSocket.getOutputStream()),
Zygote.SOCKET_BUFFER_SIZE);
final DataInputStream usapReader =
new DataInputStream(usapSessionSocket.getInputStream());
// 写入新进程的args参数
usapWriter.write(msgStr);
// 刷新数据
usapWriter.flush();
Process.ProcessStartResult result = new Process.ProcessStartResult();
// 获取创立出的新进程的pid
result.pid = usapReader.readInt();
if (result.pid >= 0) {
// 回来新进程的相关成果
return result;
} else {
throw new ZygoteStartFailedEx("USAP specialization failed");
}
}
}
}
3. 重回Zygote
3.1 大致流程
这儿会先解说下大体流程,让各位有些形象。便利了解后边代码。
- Zygote进程会履行runSelectLoop办法,其内部是一个while(true)循环, 正常情况下会履行Os.poll(pollFDs, pollTimeoutMs); 使Zygote进程进入休眠。
- 当接收到割裂进程的消息时,Zygote该进程会被唤醒。经过Zygote.forkAndSpecialize割裂进程。
- 两个进程经过回来pid的不同(子进程回来pid为0,Zygote进程回来pid为子进程的pid),履行不同的代码。
- 子进程跳出while循环,经过反射履行ActivityThread的main办法。
- Zygote 进程会再次进入while(true)循环中,履行Os.poll(pollFDs, pollTimeoutMs); 使进程进入休眠,直到下次割裂进程。
3.2 Zygote循环
先看下ZygoteServer中的runSelectLoop() 办法。 该办法内部的Os.poll(pollFDs, pollTimeoutMs); 会使Zygote进程休眠。 ZygoteConnection.processOneCommand() 办法会履行割裂进程的办法。
详细代码如下:
/**
* Server socket class for zygote processes.
*/
class ZygoteServer {
/**
* Set by the child process, immediately after a call to {@code Zygote.forkAndSpecialize}.
*/
private boolean mIsForkChild;
void setForkChild() {
mIsForkChild = true;
}
/**
* Runs the zygote process's select loop. Accepts new connections as
* they happen, and reads commands from connections one spawn-request's
* worth at a time.
*/
Runnable runSelectLoop(String abiList) {
ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
ArrayList<ZygoteConnection> peers = new ArrayList<>();
while (true) {
int[] usapPipeFDs = null;
StructPollfd[] pollFDs;
int pollReturnValue;
try {
// 此处进行进程休眠
pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
if (pollReturnValue == 0) {
// 代码省掉......
} else {
boolean usapPoolFDRead = false;
while (--pollIndex >= 0) {
if (pollIndex == 0) {
// Zygote server socket
// 代码省掉......
} else if (pollIndex < usapPoolEventFDIndex) {
// Session socket accepted from the Zygote server socket
try {
ZygoteConnection connection = peers.get(pollIndex);
// processOneCommand办法中会割裂出子进程。
// 子进程会调用setForkChild将mIsForkChild设置为true
final Runnable command = connection.processOneCommand(this);
// 子进程mIsForkChild为true
if (mIsForkChild) {
return command;
} else {
// 代码省掉......
}
} catch (Exception e) {
// 异常处理,省掉......
} finally {
// Reset the child flag
mIsForkChild = false;
}
} else {
// 代码省掉......
}
}
}
}
}
}
3.3 Fork进程
Zygote进程fork出新的进程。一起经过回来的pid的差异,来区分新进程和 Zygote进程。
因为pid不一致,导致两个进程后续的履行代码不一样。然后走向不同的人生。此处能够参考本系列的上篇文章AMS的来源,SystemServer的前世此生
终究子进程会调用RuntimeInit.findStaticMain() 办法,经过反射履行ActivityThread的main办法。
这便是为什么咱们App是从Activity的main办法发动的原因。
/**
* A connection that can make spawn requests.
*/
class ZygoteConnection {
/**
* 回来一个Runnable,内容为fork子进程。
* zygote进程此处回来的pid为子进程pid,该办法回来值为null
* 子进程,回来的pid为0,该办法回来handleChildProc办法的回来值
*/
Runnable processOneCommand(ZygoteServer zygoteServer) {
// 读取传给Zygote进程的参数列表
String[] args = Zygote.readArgumentList(mSocketReader);
ZygoteArguments parsedArgs = new ZygoteArguments(args);
// 经过native办法fork出进程。
// zygote进程的pid为子进程的pid。
// fork出的子进程的pid为0
int pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
try {
if (pid == 0) {
// 子进程中的ZygoteServer的mIsForkChild设置为true
zygoteServer.setForkChild();
// 子进程关闭socket
zygoteServer.closeServerSocket();
// 处理子进程,内部会经过反射调用ActivityThread的main办法
return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
} else {
return null;
}
}
}
// 处理子进程
private Runnable handleChildProc(ZygoteArguments parsedArgs,
FileDescriptor pipeFd, boolean isZygote) {
// 设置进程称号
Zygote.setAppProcessName(parsedArgs, TAG);
// 这儿会经过反射,调用ActivityThread的main办法
return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mRemainingArgs, null /* classLoader */);
}
}
4. 新的进程,新的人生
4.1 ActivityThread类
新的进程中会履行ActivityThread的main办法。创立Looper。履行attach办法,终究履行Looper.loop(); 进入循环等候。
这儿留意,在attach办法中,会经过ServiceManager获取AMS服务。然后将ApplicationThread传递给AMS,以便利完成跨进程通讯。
这儿要提出一点,ApplicationThread目标是子进程和AMS完成跨进程通讯的重要目标。子进程将ApplicationThread目标传递给AMS,AMS会调用传递来的ApplicationThread目标来让子进程履行一些办法。
public final class ActivityThread {
private final ResourcesManager mResourcesManager;
@UnsupportedAppUsage
ActivityThread() {
mResourcesManager = ResourcesManager.getInstance();
}
public static void main(String[] args) {
// 预备looper
Looper.prepareMainLooper();
// 创立ActivityThread目标
ActivityThread thread = new ActivityThread();
// attach办法
thread.attach(false, startSeq);
// 履行loop,等候handler传递消息
Looper.loop();
}
// binder目标,用来跨进程通讯
final ApplicationThread mAppThread = new ApplicationThread();
@UnsupportedAppUsage
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
// 此处获取AMS的binder实例,用来跨进程通讯
final IActivityManager mgr = ActivityManager.getService();
try {
// 跨进程通讯,将mAppThread,传给AMS
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} else {
// SystemServer中履行的代码,此处省掉......
}
}
4.2 AMS跨进程通讯
因为在attach办法中履行mgr.attachApplication办法。 mgr是AMS实例。所以该办法会跨进程通讯,将mAppThread传递给AMS。
一起履行从子进程传递来的ApplicationThread类中的bindApplication办法。该办法会在子进程中创立Application目标,并履行它的onCreate办法。
而下方的mAtmInternal.attachApplication这句代码,会在ATMS中跨进程通讯,告知子进程创立Activity目标,并履行它的onCreate办法。
详细代码如下:
public class ActivityManagerService extends IActivityManager.Stub{
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
// 调用attachApplicationLocked办法
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
}
}
@GuardedBy("this")
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
// 代码省掉......
// 此处跨进程调用调用App进程中的ApplicatioThread的bindApplication办法
// 在App进程中,创立Applicaiton,履行onCreate办法
thread.bindApplication(processName, appInfo, providerList,
instr2.mClass,
profilerInfo, instr2.mArguments,
instr2.mWatcher,
instr2.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.mDisabledCompatChanges);
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
// 履行,ATMS的attachApplicaiton办法,
// 跨进程调用,调用App进程的ActivitThread目标的attachApplicaiton办法
//创立Acitivity履行onCreate办法
boolean didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
}
return true;
}
}
4.3 创立Application
这儿会经过上面代码中的thread.bindApplication 跨进程通讯。调用ActivityThread的内部类 ApplicationThread 的 bindApplication办法。
终究在子进程中创立Application,履行Application的onCreate办法。
详细如下面代码所示:
public final class ActivityThread extends ClientTransactionHandler {
Application mInitialApplication;
final H mH = new H();
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public final void bindApplication(String processName, ApplicationInfo appInfo,...) {
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
// 调用 Handler
sendMessage(H.BIND_APPLICATION, data);
}
}
class H extends Handler {
public static final int BIND_APPLICATION = 110;
@UnsupportedAppUsage
public static final int EXIT_APPLICATION = 111;
public void handleMessage(Message msg) {
switch (msg.what) {
case BIND_APPLICATION:
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
break;
case EXIT_APPLICATION:
if (mInitialApplication != null) {
mInitialApplication.onTerminate();
}
Looper.myLooper().quit();
break;
}
}
}
@UnsupportedAppUsage
private void handleBindApplication(AppBindData data) {
Application app;
// data.inf是LoadApk目标。创立application目标
app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
// 履行,Application的onCreate办法
mInstrumentation.callApplicationOnCreate(app);
}
}
4.4 创立Activity
经过ATMS中的attachApplication办法。会经过履行ActivityStackSupervisor的realStartActivityLocked办法。
此处会经过ClientTransaction以及ClientLifecycleManager等类的流转,终究会调用ActivityThread中的handleLaunchActivity 办法。对ClientTransaction和ClientLifecycleManager怎么履行事情流转的同学,能够进源码中检查。此处只说定论,那便是,又再次跨进程通讯,让App进程调ActivityThread的handleLaunchActivity办法。
public class ActivityStackSupervisor{
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
// 对应ActivityThread中的 handleLaunchActivity 办法
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),省掉......));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
return true;
}
}
handleLaunchActivity终究会调用performLaunchActivity办法。内部创立了Activity目标,一起履行了attach,onCreate办法,而且设置了主题等操作。详细如下图代码。
public final class ActivityThread extends ClientTransactionHandler {
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
final Activity a = performLaunchActivity(r, customIntent);
return a;
}
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
// 因为bindApplication现已创立过application
// 所以此处回来,前文中创立的application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
// Activity resources must be initialized with the same loaders as the
// application context.
appContext.getResources().addLoaders(
app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
// attach 办法
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
// 设置主题
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
// 履行onCreate办法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
}
r.setState(ON_CREATE);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;
}
}
至此,一个App的发动进程就讲完了。
- 从最初的告知zygote创立子进程,在子进程中履行ActivityThread 的main办法。
- 再到,将applicationThread目标传递给AMS,调用AMS的attachApplication办法。
- 再在AMS进程中调用bindApplicaiton让子进程创立application目标。
- 以及经过ClientLifecycleManager和ClientTransaction来履行,子进程中的handleLaunchActivity办法,终究调用performLaunchActivity办法来创立activity目标,履行activity的onCreate办法。
5. 全体流程
下图为Zygote进程从fork出SystemServer到创立子进程的activity的全体的图解。
终究
终究,咱们再来看一下文章最开端的几个问题。是否就有了相应的答案呢。
期望各位喜爱的小伙伴,能够点个赞,点个重视。你们的赞和重视便是我的动力。感谢各位大大了。