Activity发动流程因为篇幅较长,将分述两篇文章进行解说。
上文主要进行概念提要和流程总述,下文主要从源码视点逐步探寻流程经过
一文搞定面试 | Activity发动流程之冷热发动(上)
一文搞定面试 | Activity发动流程之冷热发动(下)
一图看懂
在上一篇中,已经大致将流程从概念上进行梳理了一遍,在结束中给出了这么一张图,那么本文将从源码视点还原这张图的全部流程和细节。本文依据Android 31
源码进行解析
图片取自 # Android Application 发动流程剖析及其源码调用探求
源码深入
startActivity的起点
关于Launcher点击使用图标来说,也是startActivity的调用。终究均经过Instrumentation
这个工具类,向AMS建议startActivity
的Binder通讯行为
// Activity.java
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
startActivity
>>>startActivityForResult(这儿有许多分支,但终究都会走下一路径)
>>>Instrumentation.execStartActivity
// Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// ……
IApplicationThread whoThread = (IApplicationThread) contextThread;
// ……
// 留意下面的ActivityTaskManager.getService()
// 这儿即相当于调用了AMS的startActivity()
// 同时重视下第一个参数,whoThread,传入的是IApplicationThread目标,而这个来源于Activity对应的ActivityThread里的mAppThread
// 也便是使用进程创立之初创立的主线程,而IApplicationThread是Stub,即Binder的服务端
// 这儿留个心眼,后边有呼应
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);
// ……
}
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
// 这儿从ServiceManager中获取到了ACTIVITY_TASK_SERVICE即AMS的Binder目标,并终究将其包装成Proxy回来供外部调用
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
AMS创立Activity环节
AMS中的startActivity现在均交由ActivityTaskManagerService进行代理,当时已进入System Server进程,在该流程return前,Client即建议startActivity的使用进程均处于挂起状态
// ActivityTaskManagerService.java
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());
}
ActivityTaskManagerService.startActivity() >>> startActivityAsUser()
>>> ActivityStarter.execute() >>> executeRequest() >>> startActivityUnchecked() >>> startActivityInner()
>>> RootWindowContainer.resumeFocusedTasksTopActivities()
>>> Task.resumeTopActivityUncheckedLocked() >>> resumeTopActivityInnerLocked()
>>> ActivityTaskSupervisor.startSpecificActivity()
// ActivityStarter.java
// 这个类的含义很好了解,发动器嘛
private int executeRequest(Request request) {
// ……这个办法内能够看到 确定Intent和flag应怎么转换为活动以及相关的使命和仓库
// r是新build出来的ActivityRecord目标
startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
restrictedBgActivity, intentGrants);
}
// ActivityTaskSupervisor.java
// 这是之前说到过的大管家
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()) {
// 热发动和暖发动流程,最后会一起说到,先不讲,先继续看冷发动fork进程
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;
}
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
// 冷发动,创立使用进程
final boolean isTop = andResume && r.isTopRunningActivity();
// 这一块关于socket是怎么发送的,待弥补
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
Zygote孵化使用进程
Zygote的主要职责便是孵化进程,其间包含管理AMS的System Server进程也由它进行孵化。通讯选用Soceket Server继续监听。新的子使用进程孵化完成后,将会反射调用ActivityThread.main()
// ZygoteInit.java
// Zygote进程发动类
public static void main(String[] argv) {
caller = zygoteServer.runSelectLoop(abiList);
}
// ZygoteServer.java
// Zygote Socket服务端
Runnable runSelectLoop(String abiList) {
while (true) {
// connect便是AMS Client建议的连接恳求
try {
ZygoteConnection connection = peers.get(pollIndex);
final Runnable command =
connection.processCommand(this, multipleForksOK);
} catch (Exception e) {
// 这儿贴一段官方注释,留意processCommand将会履行ActivityThread的main办法
// We're in the child so any exception caught here has happened post
// fork and before we execute ActivityThread.main (or any other
// main() method). Log the details of the exception and bring down
// the process.
}
}
}
// ZygoteConnection.java
Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {
// 我们的目的是为了看进程fork,所以找关键词:进程号pid
// 这儿Zygote完成了子进程fork创立
// 然后依据该办法内的注释,我们又重视到了handleChildProc()
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.mAllowlistedDataInfoList, parsedArgs.mBindMountAppDataDirs,
parsedArgs.mBindMountAppStorageDirs);
// ……
return handleChildProc(parsedArgs, childPipeFd,
parsedArgs.mStartChildZygote);
}
private Runnable handleChildProc(ZygoteArguments parsedArgs,
FileDescriptor pipeFd, boolean isZygote) {
// 因为需求fork子进程,所以isZygote为true,走childZygoteInit
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
parsedArgs.mDisabledCompatChanges,
parsedArgs.mRemainingArgs, null /* classLoader */);
} else {
// 这儿的调用链就很简略了,就反射履行main办法,而class目标上面的注释里就说到了,是ActivityThread
// 至于这块逻辑怎么就确认是ActivityThread,我解说不了hh
return ZygoteInit.childZygoteInit(
parsedArgs.mRemainingArgs /* classLoader */);
}
}
使用进程创立后
使用进程创立后,被反射履行了ActivityThread.main(),内容比较少,主体流程便是将自身ActivityThread实例attach给AMS
// ActivityThread.java
public static void main(String[] args) {
// 关于looper的内容就不多阐述了,对handler这块想要了解的就去翻下我前面的文章叭
Looper.prepareMainLooper();
// 这儿就要开端绑定了
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
private void attach(boolean system, long startSeq) {
if (!system) {
// 因为传进来的是false,所以走这儿
final IActivityManager mgr = ActivityManager.getService();
try {
// 那这个老生常谈了,那便是去AMS看下文喽
// 所以当AMS完成attach后,该线程才会唤醒,去履行之后的loop()
// 前面startActivity中调用AMS时,传入了同样的参数类型:IApplicationThread
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
使用进程向AMS建议恳求时,经过ServiceManager得到AMS注册的Binder然后得到Proxy代理类,而AMS需求向使用进程建议调度时,则经过作为服务端时接受的IApplicationThread目标以进行工作

// ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
// 因为里边的办法大同小异,随意选取一个眼熟的,四大组件之一的Service
// sendMessage经过外部类ActivityThread发送handler消息,终究会回调履行Service.onCreate()
// 那把其他办法大致能够扫一眼,四大组件的一些处理皆需求经过这儿建议
// 那建议的客户端应该便是AMS了,所以为什么说AMS是四大组件的集中管理者
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}
}
// handleMessage
case CREATE_SERVICE:
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
("serviceCreate: " + String.valueOf(msg.obj)));
}
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
AMS绑定使用进程
AMS完成了Application创立后,告诉ActivityThread进行生命周期回调
ActivityManagerService.attachApplication() >>> attachApplicationLocked() // 这儿对ProcessRecord进行了一些状态设置……
>>> IApplicationThread.bindApplication() // 这儿又回去了,不用解说了吧,在ActivityThread里发送对应的handler消息
>>> ActivityThread.handleBindApplication()
// 这儿就挨近尾声了,完成了application的创立,onCreate这块是在主线程,所以留意尽可能避免耗时操作
>>> makeApplication() + mInstrumentation.callApplicationOnCreate
是不是觉得哪里不对劲?Activity还没发动呢!想一想一件事,Binder的挂机机制,回到AMS中调用bindApplication
的后边
// ActivityManagerService.java
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
// ……
thread.bindApplication()
// ……
// 这个时分,Application已经完成了onCreate()
// 一开端我也找了好久,许多文章中也没有说到这一茬,直到我仔细看了官方注释
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
// attachApplication全局搜了下只剩下RootWindowContainer里还有了,去看看吧
// 当然喔,这儿仅仅我的想法,可是他们的办法名、入参、回来值如出一辙,我也就不多想了
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
}
// RootWindowContainer
boolean attachApplication(WindowProcessController app) throws RemoteException {
// 看来看去,startActivityForAttachedApplicationIfNeeded这个最顺眼
final PooledFunction c = PooledLambda.obtainFunction(
RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
PooledLambda.__(ActivityRecord.class), app,
rootTask.topRunningActivity());
rootTask.forAllActivities(c);
c.recycle();
}
private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
WindowProcessController app, ActivityRecord top) {
// realStartActivityLocked这个办法熟不熟悉
if (mTaskSupervisor.realStartActivityLocked(r, app,
top == r && r.isFocusable() /*andResume*/, true /*checkConfig*/)) {
mTmpBoolean = true;
}
}
假如你忘了realStartActivityLocked在哪见过的话,我帮你回想回想。现在想起来了嘛
// ActivityTaskSupervisor.java
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;
}
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
// 冷发动,创立使用进程
final boolean isTop = andResume && r.isTopRunningActivity();
// 这一块关于socket是怎么发送的,待弥补
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}
Activity终究发动
关于这块的调用链,不同版本源码可能有所不同,但终究都将经过ActivityThread.performLaunchActivity
或相似办法名展开。当然这儿举例的是冷发动状态下,Activity处于ON_CREATE
阶段的状况,假如是热发动的话,只需求快速进行状态康复就好了
ActivityTaskSupervisor.realStartActivityLocked()
>>> ClientLifecycleManager.scheduleTransaction()
>>> ClientTransaction.schedule()
>>> IApplicationThread.scheduleTransaction()
// 这儿在ActivityThread里没找到对应的办法,在其父类中找到
>>> ActivityThread:ClientTransactionHandler.scheduleTransaction() // 发送了EXECUTE_TRANSACTION
>>> TransactionExecutor.execute() >>> executeCallbacks() >>> cycleToPath() >>> performLifecycleSequence()
// 这次是父类引证,子类实现了
// 当然这儿是依据lifecycle生命周期改变调度对应办法,热发动就不需求launchActivity了
>>> ActivityThread:ClientTransactionHandler.handleLaunchActivity()
>>> ActivityThread.performLaunchActivity()
// 包含其他生命周期分发也都能看到
>>> Instrumentation.callActivityOnCreate()
>>> Activity.performCreate()
现在再来比照一下这张图,有所区别的便是14.1和14.2的办法名,但整体调用链却是如出一辙。关于Activity发动的整体流程,无论是冷发动仍是热发动,能够不用过于重视细节的办法调用链,应该关怀如图几个具有关键职能的类之间的调度流通。
在厘清这个之后,再回头去过一遍源码细节,相信你会有所收成
魂灵发问
暂无,等待大佬们供给面试问题……欢迎谈论
拜读
第一篇主攻源码流程,第二篇主攻概念及思路解析,两篇的阅读顺序能够不一定,但结合起来,十分有助于了解
# Android使用发动流程
# Android使用发动流程剖析
# Android Application 发动流程剖析及其源码调用探求
假如觉得本文对你有协助,不妨
点赞+保藏+重视
支持一波,感谢肯定和喜爱当然,更希望
初读点赞
、再读保藏
、三而重视