前言
為了面試與被面試閱讀了Activity的啟動流程,整理了這篇文章。 之前一直好奇為什麼Android面試經常問Activity啟動流程,因為在工作中沒有相關的實踐。閱讀完原始碼以後才發現,Activity啟動流程中包含了許多知識,例如Activity的啟動模式如何處理、外掛化的hook點等等。不過由於原始碼冗長,本文只分析Activity的啟動流程。
閱讀建議:
1、分析基於Android 9.0原始碼,整理了3張流程圖。由於圖文排版稀疏,建議新建一個API28的工程配合流程圖閱讀原始碼,如果發現文章有什麼問題,可以聯絡我。
2、原始碼冗長,閱讀需要耐心。
3、紙上得來終覺淺,絕知此事要躬行。
4、如果流程圖不能放大預覽,請閱讀原文fiftykg.com
Activity在應用內啟動流程
話不多說,先上圖,流程圖1:
簡單介紹一下涉及的類:
工具類,包裝了ActivityManagerService的呼叫。一些外掛化方案就是通過hook該類實現的,例如didi的VirtualApk
Android核心服務,負責排程各應用程式,管理四大元件。實現了IActivityManager介面,應用程式能通過Binder機制呼叫系統服務。
Activity啟動的工具類,處理啟動activity的各種flag。
管理所有應用的Activity的棧,其中mFocusedStack就是當前應用的activity棧。
啟動Activity的訊息。收到訊息後執行execute方法啟動activity。
應用的主執行緒。
接下來開始分析流程:
流程圖1,第1-3步,Activity的startActivity會呼叫startActivityForResult。當應用已經啟動時,會先呼叫startActivityFromChild。但是無論應用是否啟動,最後都會呼叫Instrumentation.execStartActivity
。
正如前面所說,ActivityManagerService實現了IActivityManager.aidl
介面,提供了應用程式呼叫系統服務的方法,而Instrumentation包裝了ActivityManagerService的呼叫。
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
...
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
...
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
int requestCode, @Nullable Bundle options) {
...
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, child,
intent, requestCode, options);
...
}
複製程式碼
流程圖1,第4步,Instrumentation呼叫ActivityManagerService的startActivity
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
...
try {
...
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), 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;
}
複製程式碼
流程圖1,第5-6步,ActivityManagerService建立ActivityStarter並執行。
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
...
return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}
複製程式碼
流程圖1,第7步,由於第6步setMayWait將mayWait設定為true,所以執行startActivityMayWait方法。
ActivityStarter setMayWait(int userId) {
mRequest.mayWait = true;
mRequest.userId = userId;
return this;
}
int execute() {
try {
if (mRequest.mayWait) {
return startActivityMayWait(...);
} else {
return startActivity(...);
}
} finally {
onExecutionComplete();
}
}
複製程式碼
流程圖1,第8-11步,ActivityStarter處理啟動activity的intent和flag比較繁瑣,最後會呼叫ActivityStackSupervisor的resumeFocusedStackTopActivityLocked。
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
...
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || !r.isState(RESUMED)) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
} else if (r.isState(RESUMED)) {
...
}
return false;
}
複製程式碼
流程圖1,第12步,resumeTopActivityInnerLocked是一個非常冗長的方法,該方法會判斷棧中是否有需要啟動的Activity,判斷Activity是否在棧頂等等。如果需要啟動的Activity沒有被建立,就會執行流程圖13步ActivityStackSupervisor的startSpecificActivityLocked方法。
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next.app != null && next.app.thread != null) {
...
}else{
// Whoops, need to restart this activity!
...
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
}
複製程式碼
流程圖1,第13-14步,startSpecificActivityLocked方法中先判斷App是否啟動,如果啟動則執行realStartActivityLocked。如果未啟動則呼叫ActivityManagerService.startProcessLocked方法啟動App。 為了分析方便,我們先看App啟動的情況。在realStartActivityLocked方法中,ActivityManangerService會呼叫應用程式的介面,最終執行ClientTransaction的callBack,也就是LaunchActivityItem。這個呼叫過程將在稍後分析。
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
if (app != null && app.thread != null) {
try {
...
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
...
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
r.appToken);
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, mService.isNextTransitionForward(),
profilerInfo));
...
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
}
複製程式碼
流程圖1,第15步,LaunchActivityItem的execute方法執行了ClientTransactionHandler的handleLaunchActivity。而這個ClientTransactionHandler就是ActivityThread。至於為什麼是ActivityThread,可以看第二部分。
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
複製程式碼
流程圖1,第16-19,ActivityThread執行handleLaunchActivity方法,呼叫真正Activity啟動方法performLaunchActivity。 performLaunchActivity中呼叫Instrumentation.newActivity方法建立Activity物件! 建立完成後,performLaunchActivity會繼續呼叫Instrumentation.callActivityOnCreate。這裡往下走就會呼叫Activity.OnCreate。
// ActivityThread.java:
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
...
final Activity a = performLaunchActivity(r, customIntent);
...
return a;
}
// ActivityThread.java:
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
} catch (Exception e) {
...
}
try {
...
if (activity != null) {
...
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()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
}
...
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
...
}
return activity;
}
// Instrumentation.java:
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
String pkg = intent != null && intent.getComponent() != null
? intent.getComponent().getPackageName() : null;
return getFactory(pkg).instantiateActivity(cl, className, intent);
}
// AppComponentFactory.java:
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
@Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Activity) cl.loadClass(className).newInstance();
}
複製程式碼
流程圖1,第20-21,Instrumentation.callActivityOnCreate中呼叫Activity的performCreate。performCreate呼叫Activity.onCreate!
// Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
// Activity.java
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
...
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
...
}
複製程式碼
IApplicationThread & IActivityManager
上面流程中最難理解的大概就是第15步了,clientTransaction中新增的LaunchActivityItem是如何被執行的?要理解這一步就需要先了解一下系統與應用之間的通訊。
Android程式間通過Binder機制進行通訊。AMS(ActivityManagerService)與應用程式之間的通訊,Android設計了IApplicationThread與IActivityManager兩個介面。 兩個通訊介面都是單向的: IApplicationThread是AMS請求應用程式的介面。 IActivityManager是應用程式請求AMS的介面。
public class ActivityManagerService extends IActivityManager.Stub
// ActivityThread的內部類
private class ApplicationThread extends IApplicationThread.Stub
複製程式碼
再來看一下,上面流程第15步的分解流程,流程圖2:
流程圖2,第3步,mClient就是IApplicationThread。
private IApplicationThread mClient;
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
複製程式碼
流程圖2,第4步,ApplicationThread中scheduleTransaction方法直接呼叫外部類ActivityThread的scheduleTransaction,但是ActivityThread.java中沒有scheduleTransaction方法,而是在父類ClientTransactionHandler。
// ApplicationThread
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
//ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
複製程式碼
流程圖2,第5步,ClientTransactionHandler中發了一個handler訊息EXECUTE_TRANSACTION。這個Handler就是ActivityThread的子類H。在H的handleMessage中可以找到EXECUTE_TRANSACTION的處理。
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
transaction.recycle();
}
break;
複製程式碼
最終會在TransactionExecutor中取出LaunchActivityItem,執行execute。也是Activity啟動流程圖中的第15步。
AMS是何時獲取到IApplicationThread? App如何獲取IActivityManager? 答案就在ActivityThread.main方法中,main中呼叫了attach方法。
// ActivityThread.java
private void attach(boolean system, long startSeq) {
...
if (!system) {
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} else {
//system
}
...
}
複製程式碼
App程式在啟動時通過ActivityManager獲取單例的IActivityManager,利用IActivityManager的attachApplication介面將IApplicationThread註冊到AMS。這樣就實現了App與AMS的通訊。
App的啟動流程
剛才提到了ActivityThread的main方法,這是應用程式的入口。在Activity啟動流程中,第13步startSpecificActivityLocked,如果App未啟動mService.startProcessLocked就會走到ActivityThread.main方法。
接下來看一下App的啟動流程,流程圖3:
流程圖3,第14-15步,startSpecificActivityLocked中判斷app未啟動進入AMS的startProcessLocked,startProcessLocked經過多次過載呼叫走到startProcess,startProcess呼叫Process.start啟動程式。 這裡注意下,Process.start的第一個引數,在其中一個startProcessLocked方法中賦值為"android.app.ActivityThread",搜尋字串就可以找到!
// ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// application is not running
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
// ActivityManagerService.java
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")) {
// webview process
} 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});
}
checkTime(startTime, "startProcess: returned from zygote!");
return startResult;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
複製程式碼
流程圖3,第16步,Process.start中出現了著名的ZygoteProcess! 傳說中Android的所有程式起源於Zygote,Process類只是對Zygote的包裝而已。
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);
}
複製程式碼
流程圖3,第17-20步,zygoteProcess.start呼叫zygoteProcess.startViaZygote。startViaZygote中通過socket與zygote通訊,啟動app程式,zygoteSendArgsAndGetResult方法返回app程式的pid。
private Process.ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int runtimeFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String invokeWith,
boolean startChildZygote,
String[] extraArgs)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
// --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);
...
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
複製程式碼
接下來就是需要尋找argsForZygote中的引數在哪裡解析,在zygoteSendArgsAndGetResult方法中有這樣一段註釋:
/**
* See com.android.internal.os.SystemZygoteInit.readArgumentList()
* Presently the wire format to the zygote process is:
* a) a count of arguments (argc, in essence)
* b) a number of newline-separated argument strings equal to count
*
* After the zygote process reads these it will write the pid of
* the child or -1 on failure, followed by boolean to
* indicate whether a wrapper process was used.
*/
複製程式碼
然而找不到SystemZygoteInit這個類! 既然argsForZygote中引數是一些hardcode的字串,那解析的地方應該也是hardcode。所以搜了一下引數。 果然在ZygoteInit.java和ZygoteConnection.java中發現了這些引數。ZygoteInit是zygote程式啟動類,main方法中建立了ZygoteServer。由ZygoteServer監聽Socket請求,並執行相應的命令。ZygoteServer與客戶端的通訊協議定義在ZygoteConnection.Arguments中。
流程圖3,第21-22步,經過上面一波分析,我們看到ZygoteServer的runSelectLoop方法中,接收到Socket請求後,執行了ZygoteConnection.processOneCommand。
Runnable runSelectLoop(String abiList) {
while (true) {
...
ZygoteConnection connection = peers.get(i);
final Runnable command = connection.processOneCommand(this);
...
}
複製程式碼
流程圖3,第23-24步,processOneCommand中通過readArgumentList方法讀取引數,建立Arguments物件時,在Arguments.parseArgs方法中解析引數。將解析後的引數傳入Zygote.forkAndSpecialize建立子程式。
Runnable processOneCommand(ZygoteServer zygoteServer) {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
throw new IllegalStateException("IOException on command socket", ex);
}
...
parsedArgs = new Arguments(args);
....
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
parsedArgs.instructionSet, parsedArgs.appDataDir);
....
}
複製程式碼
在readArgumentList中看到了一段與zygoteSendArgsAndGetResult方法遙相呼應的註釋
/**
* See android.os.Process.zygoteSendArgsAndGetPid()
* Presently the wire format to the zygote process is:
* a) a count of arguments (argc, in essence)
* b) a number of newline-separated argument strings equal to count
*
* After the zygote process reads these it will write the pid of
* the child or -1 on failure.
*/
複製程式碼
然而在Process中也找不到zygoteSendArgsAndGetPid。感覺是歷史程式碼的註釋,誤導啊!
流程圖3,第25步,processOneCommand執行完forkAndSpecialize後,在子程式(pid=0)中,執行handleChildProc進行子程式初始化。
Runnable processOneCommand(ZygoteServer zygoteServer) {
...
pid = Zygote.forkAndSpecialize(...);
try {
if (pid == 0) {
// in child
zygoteServer.setForkChild();
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
return handleChildProc(parsedArgs, descriptors, childPipeFd,
parsedArgs.startChildZygote);
} else {
// In the parent. A pid < 0 indicates a failure and will be handled in
// handleParentProc.
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
handleParentProc(pid, descriptors, serverPipeFd);
return null;
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
複製程式碼
流程圖3,第26步,handleChildProc中,invokeWith是socket引數"--invoke-with",在ActivityManagerService的startProcessLocked中賦值,只有在debug的情況下才!null。 isZygote是引數"--start-child-zygote",在ZygoteProcess.start方法中為false。 所以handleChildProc會走到ZygoteInit.zygoteInit。 這裡比較奇怪,為什麼不是走childZygoteInit,希望有想法的朋友告知一下=。=
private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
FileDescriptor pipeFd, boolean isZygote) {
...
if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.remainingArgs);
// Should not get here.
throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
} else {
if (!isZygote) {
return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
null /* classLoader */);
} else {
return ZygoteInit.childZygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}
}
複製程式碼
流程圖3,第27-28步,zygoteInit中執行RuntimeInit.applicationInit,applicationInit呼叫findStaticMain,反射ActivityThread.main方法!
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
...
final Arguments args = new Arguments(argv);
...
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
Class<?> cl;
try {
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
...
return new MethodAndArgsCaller(m, argv);
}
複製程式碼
流程圖3,第29-33步,回到ActivityThread.main方法中,走到attach中,向AMS註冊IApplicationThread,經過多次attachApplicationLocked走到Activity的啟動流程,ActivityStackSupervisor的realStartActivityLocked,也就是流程圖1的第14步。
// ActivityManagerService.java
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(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
複製程式碼
巨人的肩膀
老羅:Android應用程式內部啟動Activity過程(startActivity)的原始碼分析
Android四大元件之Activity--應用程式與系統程式的通訊
ps: 原始碼閱讀過程中,遇得了許多疑惑的地方。一方面是能力有限,需要多參考前輩的文章,另一方面原始碼也並非完美,程式碼中也有許多todo存在,也許還能發現一些bug。對於ZygoteProcess.zygoteSendArgsAndGetResult()與ZygoteConnection.readArgumentList中出現的誤導註釋,給google提了一個issue,就當閱讀原始碼的紀念了。
以上。
如果覺得文章還不錯,幫忙點個贊。