前言
其实早在几年前,我就有一个疑问。
- 为什么我们的逻辑代码写在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就会将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。
从am这里的启动调用过程过于复杂,个人认为记这个调用流程没有任何意义。只要记住一些关键方法即可。 我尽量写的能让各位记住。或者大家只记住关键方法以及最后结果亦可。
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进程。
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值不一致,导致两个进程后续的执行代码不一样。从而走向不同的人生。
最终子进程会调用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的整体的图解。
《Framework 核心知识点汇总手册》
Handler 机制实现原理部分:
1.宏观理论分析与Message源码分析
2.MessageQueue的源码分析
3.Looper的源码分析
4.handler的源码分析
5.总结
Binder 原理:
1.学习Binder前必须要了解的知识点
2.ServiceManager中的Binder机制
3.系统服务的注册过程
4.ServiceManager的启动过程
5.系统服务的获取过程
6.Java Binder的初始化
7.Java Binder中系统服务的注册过程
Zygote :
- Android系统的启动过程及Zygote的启动过程
- 应用进程的启动过程
AMS源码分析 :
- Activity生命周期管理
- onActivityResult执行过程
- AMS中Activity栈管理详解
深入PMS源码:
1.PMS的启动过程和执行流程
2.APK的安装和卸载源码分析
3.PMS中intent-filter的匹配架构
WMS:
1.WMS的诞生
2.WMS的重要成员和Window的添加过程
3.Window的删除过程
《Android Framework学习手册》:
- 开机Init 进程
- 开机启动 Zygote 进程
- 开机启动 SystemServer 进程
- Binder 驱动
- AMS 的启动过程
- PMS 的启动过程
- Launcher 的启动过程
- Android 四大组件
- Android 系统服务 - Input 事件的分发过程
- Android 底层渲染 - 屏幕刷新机制源码分析
- Android 源码分析实战
每个知识点都有左侧导航书签页,看的时候十分方便,由于内容较多,这里就截取一部分图吧。需要的读者朋友们可以进行参考:
https://0a.fit/acnLL