以Activity A 啟動(dòng) Activity B,Activity B所在進(jìn)程未啟動(dòng)為例
大體經(jīng)過(guò)已經(jīng)幾個(gè)階段:
第一步 Activity A 調(diào)用AMS 啟動(dòng)接口
這是一個(gè)binder通訊勋桶,正常啟動(dòng)Activity的方式脱衙,一般我們都會(huì)通過(guò)以下的方式啟動(dòng)一個(gè)新的Activity
startActivity(new Intent(A_Activity.this,B_Activity.class));
這是Activity類的接口侥猬,最終會(huì)調(diào)用到
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
}
}
這里關(guān)鍵點(diǎn)會(huì)調(diào)用Instrumentation 的execStartActivity方法。
frameworks/base/core/java/android/app/Instrumentation.java
源碼注釋大體意思是Instrumentation類會(huì)在應(yīng)用的任何代碼執(zhí)行前被實(shí)列化捐韩,用來(lái)監(jiān)控系統(tǒng)與應(yīng)用的交互退唠。可在以應(yīng)用的AndroidManifest.xml中<instrumentation>標(biāo)簽來(lái)注冊(cè)一個(gè)Instrumentation的實(shí)現(xiàn)荤胁。
基本上在application和activity的所有生命周期調(diào)用中瞧预,都會(huì)先調(diào)用instrumentation的相應(yīng)方法。Instrumentation另一個(gè)重要作用是提供Android組件單元測(cè)試仅政。這里不做深究垢油。
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
//核心在這一句
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;
}
ActivityManager.getService().startActivity 這一步會(huì)通過(guò)binder的方式調(diào)用到AMS的接口
第二步 收集應(yīng)用信息,pause ActivityA
startActivity --> startActivityAsUser -- > mActivityStarter.startActivityMayWait
這里會(huì)調(diào)用到類 ActivityStarter
/**
* Controller for interpreting how and then launching activities.
*
* This class collects all the logic for determining how an intent and flags should be turned into
* an activity and associated task and stack.
*/
class ActivityStarter
從注釋上看圆丹,我們了解了ActivityStarter的作用是收集所有的邏輯滩愁,用來(lái)決定如何啟動(dòng)activity, ActivityStarter又通過(guò)ActivityStackSupervisor來(lái)管理ActivityStack
略過(guò)中間環(huán)節(jié)辫封,會(huì)調(diào)用到ActivityStack的resumeTopActivityInnerLocked
boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
// ......
boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, next, false);
}
// ......
if (next.attachedToProcess()) {
try {
// ......
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.getReportedProcState(),
getDisplay().mDisplayContent.isNextTransitionForward()));
mService.getLifecycleManager().scheduleTransaction(transaction);
} catch (Exception e) {
// ......
mStackSupervisor.startSpecificActivityLocked(next, true, false);
return true;
}
// ......
} else {
// Whoops, need to restart this activity!
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
if (SHOW_APP_STARTING_PREVIEW) {
next.showStartingWindow(null /* prev */, false /* newTask */,
false /* taskSwich */);
}
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
}
if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
此處先通過(guò)startPausingLocked流程使mResumedActivity pause硝枉。
第三步 通過(guò)Zygote創(chuàng)建應(yīng)用進(jìn)程
下一步則通過(guò) ActivityStackSupervisor 中的startSpecificActivityLocked方法來(lái)執(zhí)行啟動(dòng)ActivityB流程
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;
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
這個(gè)函數(shù),先判斷ActivityB所在的進(jìn)程是否啟動(dòng)倦微,如果已經(jīng)啟動(dòng)則執(zhí)行realStartActivityLocked妻味, 如果沒(méi)有則走mService.startProcessLocked流程去啟動(dòng)一個(gè)進(jìn)程. mService為ActivityManagerService
private final void startProcessLocked(ProcessRecord app,) {
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
startResult = Process.start(entryPoint,);
synchronized (mPidsSelfLocked) {
this.mPidsSelfLocked.put(startResult.pid, app);
if (isActivityProcess) {
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
}
}
frameworks/base/core/java/android/os/Process.java
public static final ProcessStartResult start(final String processClass,) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}
frameworks/base/core/java/android/os/Process.java
public final Process.ProcessStartResult start(final String processClass,) {
try {
return startViaZygote(processClass, );
}
}
這里 entryPoint = "android.app.ActivityThread" 為啟動(dòng)的java類, 該變量會(huì)作為參數(shù)給到Process欣福。 Process.start(entryPoint,) 最終會(huì)通過(guò)socket跟Zygote通訊弧可,Zygote 會(huì)去fork一個(gè)進(jìn)程,入口就是entryPoint劣欢。
Zygote啟動(dòng)完進(jìn)程后會(huì)返回一個(gè)pid,這個(gè)pid包含在startResult里面裁良,接著會(huì)將pid和app 放入mPidsSelfLocked凿将, 并發(fā)送一個(gè)延時(shí)消息,如果ActivityThread在一定的TIMEOUT(10s)還沒(méi)向AMS報(bào)告价脾,則該消息會(huì)被執(zhí)行牧抵,AMS會(huì)去清除這個(gè)應(yīng)用的所有信息
第四步 應(yīng)用進(jìn)程啟動(dòng)及跟AMS交互
frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
Looper.loop();
}
private void attach(boolean system) {
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
這里的attach就是向AMS注冊(cè)
下面回到AMS中去執(zhí)行
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
//首先根據(jù)pid取出 ProcessRecord
app = mPidsSelfLocked.get(pid);
//thread為應(yīng)用端的binder對(duì)象,會(huì)去通知應(yīng)用端做一些Application初始化
thread.bindApplication(processName,...)
...
//處理被掛起的應(yīng)用組件(activity侨把,service犀变,broadcast),之前應(yīng)用進(jìn)程還沒(méi)被創(chuàng)建
mStackSupervisor.attachApplicationLocked(app)
...
mServices.attachApplicationLocked()
sendPendingBroadcastsLocked(app)
}
boolean attachApplicationLocked(ProcessRecord app) {
final ActivityRecord top = stack.topRunningActivityLocked();
realStartActivityLocked(activity, app,
}
stack為mFocusStack秋柄, 這一部為取出棧頂?shù)腁ctivity获枝,即我們要啟動(dòng)的activity,雖然之前activity沒(méi)啟動(dòng)骇笔,但ams里面棧的信息在啟動(dòng)進(jìn)程前都已經(jīng)準(zhǔn)備好了省店。
final boolean realStartActivityLocked() {
app.thread.scheduleLaunchActivity
}
app為ProcessRecord對(duì)象嚣崭,thread為應(yīng)用注冊(cè)到AMS的binder對(duì)象. 這里調(diào)用了應(yīng)用的scheduleLaunchActivity,從名字看表示可以加載activity了
第五步 Activity啟動(dòng)
下面就切回到ActivityThread中去執(zhí)行
public final void scheduleLaunchActivity() {
ActivityClientRecord r = new ActivityClientRecord();
sendMessage(H.LAUNCH_ACTIVITY, r);
}
通過(guò)發(fā)送消息給主線程去處理
public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY: {
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
} break;
getPackageInfoNoCheck 會(huì)去loadApk加載apk的一些信息懦傍,后面啟動(dòng)activity需要調(diào)用到雹舀,下面會(huì)去執(zhí)行的activity的生命周期
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
}
}
private Activity performLaunchActivity {
//創(chuàng)建一個(gè)Activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
// 獲取之前創(chuàng)建的Application
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
//創(chuàng)建Context, 并將Context賦值給activity
ContextImpl appContext = createBaseContextForActivity(r);
activity.attach(appContext, this, ...)
//調(diào)用到Activity onCreate函數(shù)
mInstrumentation.callActivityOnCreate(activity, r.state);
//調(diào)用到Activity onStart函數(shù)
activity.performStart();
}
大體流程可以用下圖表示
參考:
網(wǎng)絡(luò)課程 --剖析Framework面試 沖擊Android高級(jí)職位