概述
本文的内容紧接着上一篇文章Android源码探究:Activity启动流程完全解析(上),继续介绍Activity的启动流程。
主流程分析
8-1、ActivityManagerService#activityPaused(token)
经过客户端的跨进程调用,AMS的activityPaused(token)被调用了。
@Override
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
Binder.restoreCallingIdentity(origId);
}
根据token来获取Activity所在的ActivityStack,进一步调用activityPausedLocked(params..)
8-2、ActivityStack#activityPausedLocked(params..)
final void activityPausedLocked(IBinder token, boolean timeout) {
//先从ActivityStack根据token取出对应的ActivityRecord
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
//如果二者相等,表示记录的需要暂停的Activity已经暂停完毕
if (mPausingActivity == r) {
mService.mWindowManager.deferSurfaceLayout();
try {
completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
} finally {
mService.mWindowManager.continueSurfaceLayout();
}
return;
} else {
//省略...
}
}
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
这里没什么好说的,我们继续看completePauseLocked(params..)
。
8-3、ActivityStack#completePauseLocked(params..)
private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
ActivityRecord prev = mPausingActivity;
//省略大部分的代码...
if (resumeNext) {
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
if (!topStack.shouldSleepOrShutDownActivities()) {
mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
} else {
//...
}
}
}
当代码执行到这里的时候,读者应该对这个方法resumeFocusedStackTopActivityLocked(params..)
有点眼熟吧?上面已经执行过该方法了,接下来的调用链都是一样的了,最终会执行到ActivityStackSupervisor#startSpecificActivityLocked(params..)
这个方法,进行Activity的真正启动过程。
8-4、ActivityStackSupervisor#startSpecificActivityLocked(params..)
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
//获取Activity所对应的进程记录
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
getLaunchTimeTracker().setLaunchTime(r);
//如果该进程已经启动了,那么直接开始启动Activity
if (app != null && app.thread != null) {
try {
//若该Activity的flag不包含多进程标志位 或 不是安卓框架的组件
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
// 如果它是一个标记为多进程运行的平台组件,则不要添加该项,
// 因为这实际上是安卓框架的一部分,因此在进程中作为单独的apk进行跟踪是没有意义的。
app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
mService.mProcessStats);
}
//真正地启动一个Activity
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
//...
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
//代码9-1:否则,先启动一个新的进程,然后再启动Activity
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
代码的逻辑很清晰明了,主要是先判断Activity所对应的进程是否已经存在,如果存在了那就直接去执行真正的启动Activity过程;如果该进程还不存在,那么就要去启动一个进程。接下来的分析有两条路可以走,一是沿着Activity启动进行分析;二是沿着进程的启动进行分析。实际上进程的启动完毕之后也还是要进行Activity的启动的。也就是说调用了mService.startProcessLocked(params)
后,会启动新的进程,然后ActivityStackSupervisor再次调用realStartActivityLocked(params..)
在进程内启动Activity。
其实,这个调用顺序符合这一种情况:在进程A的ActivityA内启动了进程B的ActivityB,此时先暂停进程A的ActivityA,然后进程B还没有启动,那么先启动进程B,然后再启动ActivityB。
因此,接下来我们先来看怎样启动一个新的进程。
9-1、ActivityManagerService#startProcessLocked(params..)
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
private final boolean startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
//省略大部分代码...
final String entryPoint = "android.app.ActivityThread";
return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
startTime);
}
}
//一系列startProcessLocked(params..)重载方法的调用
//最终会调用下面的startProcess(params..)方法
private ProcessStartResult startProcess(String hostingType, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
try {
final ProcessStartResult startResult;
if (hostingType.equals("webview_service")) {
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
} else {
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}
return startResult;
}
}
中间省略了大部分的重载方法的调用,最后来到了Process.start(params..)
,把一系列进程有关的信息都传递了进去,根据这些信息来创建一个进程。
9-2、Process#start(params..)
这个类的源码在Android SDK内可以找到,我们直接看它的代码:
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
String[] zygoteArgs) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}
这里我们需要关注一个参数processClass
,当一个进程被启动后,以processClass
为类名的类的main(args)
函数会被调用。而这里的processClass
是代码9-1中传递进来的“android.app.ActivityThread”。那么也就是说,一个新的进程启动后,它的ActivityThread的main()函数会最先得到执行。所以,ActivityThread#main()是整个应用程序的入口。
9-3、zygoteProcess#start(params..)
代码执行到了zygoteProcess的start(params..)方法,我们先来看一下代码的执行:
public final Process.ProcessStartResult start(final String processClass,
final String niceName,int uid, int gid, int[] gids,
int runtimeFlags, int mountExternal,int targetSdkVersion,
String seInfo,String abi,String instructionSet,String appDataDir,
String invokeWith,String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
zygoteArgs);
} catch{
//...
}
}
private Process.ProcessStartResult startViaZygote(params...)throws ZygoteStartFailedEx {
ArrayList argsForZygote = new ArrayList();
//为zygote进程添加各种参数...
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
//省略...
//这里加了锁,同一时间内只允许一条线程执行创建进程的操作
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
/**
* 把新进程的参数发给zygote进程,它会创建一个子进程,并返回子进程的pid
*
*/
@GuardedBy("mLock")
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList args)
throws ZygoteStartFailedEx {
try {
//这里的跨进程通信,使用的是socket通信机制
//由于这里都是在锁的机制下执行,所以不会出现并发错误
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
//把所有新进程的参数都写入缓冲区
writer.write(Integer.toString(args.size()));
writer.newLine();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
writer.write(arg);
writer.newLine();
}
writer.flush();
// Should there be a timeout on this?
Process.ProcessStartResult result = new Process.ProcessStartResult();
//读取zygote进程返回的值,这就是新进程的pid
result.pid = inputStream.readInt();
result.usingWrapper = inputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
}
}
zygote
到底是何方神圣呢?其实在安卓系统启动的过程中,zygote进程就会被启动,它负责了整个frameworks层和application层的所有进程的创建和启动工作。也就是说,所有的进程都是它孕育出来的,都是它的子进程。同时,zygote
的中文意思受精卵
刚好与它的行为相符合。
需要注意的是,上面的代码都是运行在AMS内,只不过最后通过socket跨进程通信的方式通知了zygote进程来fork一个子进程,并且获取到了子进程的pid。该子进程创建、启动完毕之后,ActivityThread#main()
方法就得到了调用。
10-1、ActivityThread#main()
ActivityThread的main()方法可以说是我们应用程序的开端,它运行在一个新的进程空间内。当一个新的进程启动完毕开始运行后,它首先要做的是通知AMS它被启动了,因为此时AMS还等着它去执行启动Activity的后续流程呢。我们来看看main()方法做了什么工作:
public static void main(String[] args) {
//初始化环境
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("");
//为主线程准备Looper
Looper.prepareMainLooper();
//从命令行参数中获取序列号
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
//创建ActivityThread的实例
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq); //通知AMS进行绑定操作
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop(); //开启主线程的消息循环
throw new RuntimeException("Main thread loop unexpectedly exited");
}
代码的逻辑很清晰,关键的地方上面也有注释。可以看出,在main()
函数的最后,开启了主线程的消息循环,通过Handler和Looper的组合,可以不断地处理AMS、WMS发过来的消息请求等,有关主线程消息循环的内容,有兴趣的可以自行查阅相关的信息,这里不做展开讲述。我们的关注点放在thread.attach(false,startSeq)
这行代码内,我们看看它做了什么工作吧。
10-2、ActivityThread#attach(params..)
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
//获取AMS在客户端的代理对象
final IActivityManager mgr = ActivityManager.getService();
try {
//进行跨进程通信,通知AMS进行绑定操作
//这里的mAppThread就是ApplicationThread,在ActivityThread
//被实例化的时候,它也被实例化了。
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} else {
//...
}
//...
}
上面的代码出现了ApplicationThread
对象,它在前面已经出现过很多次了,它是一个Binder对象,用于AMS来跨进程与APP进行消息通信。这里通过Binder跨进程通信,调用了AMS的attachApplication(params..)方法。我们再次打开AMS的代码,找到该方法。(需要注意的是:应用程序的主线程执行完该方法之后,继续进行消息循环,以等待下一次AMS的消息。)
10-3、ActivityManagerService#attachApplication(params..)
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
//..
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
ProcessRecord app;
long startTime = SystemClock.uptimeMillis();
//根据pid来获取进程记录
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
//ProcessRecord保存了当前的IApplicationThread,即保存了客户端的一个代理对象
//AMS能根据该Binder对象快速找到所指的应用
app.makeActive(thread, mProcessStats);
//省略大部分代码...
if (app.isolatedEntryPoint != null) {
//...
} else if (app.instr != null) {
//代码11-1、跨进程调用ApplicationThread的方法,告诉APP端有关该进程的信息
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, isAutofillCompatEnabled);
} else {
//...
}
}
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
//代码12-1、告诉ActivityStackSupervisor,该app已经完成了绑定操作,可以启动一个Activity了
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
}
}
return true;
}
上面已经省略了大部分的代码,很多都是异常状态的处理以及初始化等逻辑,核心在于thread.bindApplication(params..)
和mStackSupervisor.attachApplicationLocked(app)
这两个方法的调用上。前一行代码通过IApplicationThread
跨进程通信,调用了APP端的相应方法,把有关进程的重要信息传递了过去。这样便完成从客户端到服务端的绑定操作。后一行代码,通过ActivityStackSupervisor
来找到对应的ActivityStack
,然后进行绑定,这样便完成了从服务端到客户端的绑定操作。通过这两个操作,客户端的应用程序知道了自己的应用信息、进程信息等;而服务端则知道了客户端的Binder代理对象,方便之后的跨进程操作。
11-1、ApplicationThread#bindApplication(params..)
我们先来看该方法的调用,我们又从AMS进程回到了应用进程:
public final void bindApplication(params..) {
if (services != null) {
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
}
setCoreSettings(coreSettings);
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
//省略赋值代码..
//通过Handler发送消息
sendMessage(H.BIND_APPLICATION, data);
}
由此可见,App的有关信息从AMS传递了过来,并保存在了AppBindData
这个对象内。接着,就是我们熟悉的发送消息过程,通过Handler切换到主线程,在主线程内处理这个消息。代码如下:
public void handleMessage(Message msg) {
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
Object obj = msg.obj;
if (obj instanceof SomeArgs) {
((SomeArgs) obj).recycle();
}
}
得益于主线程的消息循环,当H
接受到BIND_APPLICATION
的消息时,就能马上开始处理这个消息,处理完毕后继续消息循环。
11-2、ActivityThread#handleBindApplication(data)
private void handleBindApplication(AppBindData data) {
//省略大部分代码...
//创建上下文环境context
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
Application app;
try {
app = data.info.makeApplication(data.restrictedBackupMode, null);
//....
try {
mInstrumentation.callApplicationOnCreate(app);
}
}
}
以上省略了绝大部分的代码,很多都是初始化代码,比如加载各种库等。当Application初始化完毕之后,调用了mInstrumentation.callApplicationOnCreate(app)
。
11-3、Instrumentation#callApplicationOnCreate(app)
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
很简单,调用了Application#onCreate()
方法,也就是我们业务层常重写的方法之一,代码执行到这里,应用程序的初始化已经完成了。下面就是在应用程序的基础上启动一个Activity了。
12-1、ActivityStackSupervisor#attachApplicationLocked(app)
回到10-3的代码,继续往下执行,接着AMS就会调用mStackSupervisor.attachApplicationLocked(app)
方法,可想而知,在方法的内部,应该是要启动一个Activity了。因为一切的准备工作都已经完成了。
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
for (...) {
for (...) {
for (int i = 0; i < size; i++) {
final ActivityRecord activity = mTmpActivityList.get(i);
//如果该ActivityRecord的进程字段为空 并且进程uid与Activity的进程id相同
//并且 进程名字与Activity的进程名字相同
if (activity.app == null && app.uid == activity.info.applicationInfo.uid
&& processName.equals(activity.processName)) {
try {
//启动该Activity
if (realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
}
}
}
}
}
return didSomething;
}
上面代码的逻辑主要是遍历所有的任务栈,找到活跃的任务栈后,再在其中找到需要启动的Activity,将它启动。启动的逻辑放在了realStartActivityLocked(params..)
,终于,我们又看到了这个方法,殊途同归。
12-2、ActivityStackSupervisor#realStartActivityLocked(params..)
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
//这里进行了判断,如果有Activity处于未暂停的状态,则不能启动一个新的Activity
//由于我们是从客户端通知server来启动一个Activity的,因此已经不存在未暂停的Activity了
if (!allPausedActivitiesComplete()) {
return false;
}
final TaskRecord task = r.getTask();
final ActivityStack stack = task.getStack();
try {
//创建一个客户端的事务
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
r.appToken);
//添加callback,留意这里的添加了LaunchActivityItem
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, mService.isNextTransitionForward(),
profilerInfo));
//为该事务的目标设置为ResumeActivityItem,即启动一个Activity,并改变它
//的生命周期到Resumed状态
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
//通过事务管理器执行一个事务
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
}
return true;
}
可以看到,我们再次遇到了熟悉的ClientTransaction
,前面解析暂停Activity时也遇到它,那么接下来的逻辑应该就是与暂停的逻辑差不多了,只不过现在的ActivityLifecycleItem
变成了ResumeActivityItem
,即Activity的目标状态是resumed。接下来的调用链与前面见过的是一致的,即:ClientLifecycleManager#scheduleTransaction(clientTransaction)
——>ClientTransaction.schedule()
——>IApplicationThread.scheduleTransaction(this)
——>ActivityThread#scheduleTransaction(transaction)
——>H#handleMessage(msg)
——>TransactionExecutor#execute(transaction)
其中,通过IApplicationThread这个Binder对象进行了跨进程调用,调用了APP端的方法,此时从AMS进程切换到了我们的应用进程。紧接着,通过Handler机制切换到了主线程,并在主线程处理EXECUTE_TRANSACTION
这个消息,接着进一步交给TransactionExecutor
来处理这个事务。
13-1、TransactionExecutor#execute(transaction)
在代码7-1已经介绍过这个方法了,我们再来简单看一下就行:
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log("End resolving transaction");
}
在代码12-2中,我们有留意到初始化clientTransaction
时,为它添加了一个callback
,即LaunchActivityItem
,那么这里首先会执行executeCallbacks(transaction)
方法。
13-2、TransactionExecutor#executeCallbacks(transaction)
public void executeCallbacks(ClientTransaction transaction) {
final List callbacks = transaction.getCallbacks();
if (callbacks == null) {
// No callbacks to execute, return early.
return;
}
log("Resolving callbacks");
final IBinder token = transaction.getActivityToken();
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
//根据前面的代码,这里的size为1
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
log("Resolving callback: " + item);
//这里的Item实际上就是LaunchActivityItem.
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
//...
}
}
在方法内部调用了LaunchActivityItem
的相关方法,其中关键是LaunchActivityItem#execute(params..)
13-3、LaunchActivityItem#execute(params..)
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
//实例化一个ActivityClientRecord
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client);
//实际上调用的是ActivityThread的handleLaunchActivity方法
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
这里的ClientTransactionHandler
是ActivityThread
的父类,而ActivityThread
重写了该方法,因此我们到ActivityThread
寻找该方法。
13-4、ActivityThread#handleLaunchActivity(params..)
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
//....
final Activity a = performLaunchActivity(r, customIntent);
//...
return a;
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//省略部分代码..
ActivityInfo aInfo = r.activityInfo;
ContextImpl appContext = createBaseContextForActivity(r); //创建Context
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent); //创建一个新的Activity
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
appContext.setOuterContext(activity);
//activity绑定application
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);
if (r.isPersistable()) {
//前面创建了Activity,接下来触发它的生命周期方法
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
r.activity = activity;
}
r.setState(ON_CREATE); //设置Activity此时的状态为onCreate
mActivities.put(r.token, r);
return activity;
}
经过一系列的创建、初始化过程,终于到了Instrumentation#callActivityOnCreate(params..)
,显然,这里就是触发Activity生命周期方法的地方了。
13-5、Instrumentation#callActivityOnCreate(params..)
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
没什么好说的,下一步就是Activity#performCreate(bundle)
:
final void performCreate(Bundle icicle) {
performCreate(icicle, null);
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
mCanEnterPictureInPicture = true;
restoreHasCurrentPermissionRequest(icicle);
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle); //onCreate()生命周期方法调用
}
writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
mActivityTransitionState.readState(icicle);
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
mFragments.dispatchActivityCreated(); //告诉Fragment分发create事件
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
}
最后,终于来到了Activity#onCreate()
方法,也这就是我们应用Activity默认重写的一个方法。到了这一步,一个Activity终于真正地创建、启动成功了。但还没有完成,因为我们的目标状态是resumed,所以我们还要把Activity的状态逐步切换到onResume
状态。
让我们回到代码13-1的executeLifecycleState(transaction)
,这个方法读者应该也是熟悉的了,因为在处理pause
状态时也曾经遇到过了。那么接下来的逻辑就显而易见了,具体的逻辑就在代码7-2处,只不过现在的状态路径变成了:onStart和onResume,也就是会分别调用ActivityThread#handleStartActivity
和ActivityThread#handleResumeActivity
;接着进一步调用到Activity#performStart()
和Activity#performResume()
。最后,我们熟悉的生命周期方法onStart()
和onResume()
都会得到调用。
本文到这里就告一段落了,整篇文章很长,为耐心看到这里的你点赞~希望这篇文章能对您有所裨益,谢谢阅读!