源碼分析第二篇--Activity啓動流程,上一篇講解了Binder機制,而後立馬就在Activity啓動流程的源碼中驗證一下本身的研究成果,不要看Activity之間的跳轉只是Intent意圖的傳遞,看了源碼纔會瞭解到遠遠沒有那麼簡單。java
Instrumentation.ActivityResult ar =
// 執行啓動Activity
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
// 發送啓動Activity結果
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
複製代碼
startActivityForResult方法中有一mParent成員變量,Activity類中會有判斷mParent是否爲NULL的狀況, 而mParentmParent表明的是ActivityGroup,ActivityGroup最開始被用來在一個界面中嵌入多個Activity, 可是其在API13中已經被廢棄了,系統推薦採用Fragment來代替ActivityGroup。Instrumentation在下面會介紹,經過mInstrumentation.execStartActivity,能夠看出啓動Activity交給了Instrumentation類。android
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
/**
* ActivityMonitor能夠用來監控某個特定Intent的信息,
* 能夠經過Instrumentation.addMonitor方法來添加ActivityMonitor的實例。
* 當一個新的Activity被啓動時,會匹配Instrumentation中的ActivityMonitory實例列表
* ,若是匹配,就會累加命中計數器。ActivityMonitor也能夠被用於獲取新建立的
* Activity,經過waitForActivity方法,可返回一個匹配IntentFilter的Activity對象。
* 注:waitForActivity()方法會阻塞直到有匹配該ActivityMonitor的Activity建立完成,** 最後將該Activity返回。
*/
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
ActivityResult result = null;
if (am.ignoreMatchingSpecificIntents()) {
result = am.onStartActivity(intent);
}
if (result != null) {
am.mHits++;
return result;
} else if (am.match(who, null, intent)) {
am.mHits++;
//檢查此監視器是否阻止Activity開始或容許它們正常執行。
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
//
/**
* 此處能夠看出,啓動Activity的真正實現由
* ActivityManager.getService().startActivity方法來完成
* 經過下方源碼能夠看出ActivityManager.getService()返回的是IActivityManager
* 而IActivityManager則爲Binder接口,所以它的具體實現是ActivityManagerService
*/
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
// 用來檢查Activity的啓動狀況,若忘記在AndroidManifest.xml註冊Activity,則會在
// 此處報異常:have you declared this activity in your AndroidManifest.xml?
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
// ActivityManager.getService()
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
複製代碼
從代碼中能夠看出,此時啓動Activity由ActivityManagerService的startActivity方法執行c++
final int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
TaskRecord inTask, String reason) {
......
// mSupervisor(ActivityStackSupervisor) Task是以堆棧形式組織Activity的集合,
// 而Task又由ActivityStack管理,ActivityStackSupervisor則是管理ActivityStack的類
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
......
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
reason);
......
}
複製代碼
而startActivityLocked方法會調用本類中的startActivity方法,startActivity方法中通過一系列操做(好比:檢查權限checkStartAnyActivityPermission)後,又會調用同名重載方法startActivityweb
// 重載方法
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity) {
int result = START_CANCELED;
try {
mService.mWindowManager.deferSurfaceLayout();
// startActivityUnchecked方法裏
// 會根據啓動標誌位和Activity啓動模式來決定如何啓動一個Activity以及
// 是否要調用deliverNewIntent方法通知Activity有一個Intent試圖從新啓動它。
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
} finally {
// 若是咱們沒法繼續,將活動與任務取消關聯。
if (!ActivityManager.isStartResultSuccessful(result)
&& mStartActivity.getTask() != null) {
mStartActivity.getTask().removeActivity(mStartActivity);
}
mService.mWindowManager.continueSurfaceLayout();
}
postStartActivityProcessing(r, result
, mSupervisor.getLastStack().mStackId, mSourceRecord,mTargetStack);
return result;
}
複製代碼
startActivityUnchecked方法裏不管已什麼模式啓動Activity,都會走到ActivityStackSupervisor類中的resumeFocusedStackTopActivityLocked方法中bash
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)) {
// Kick off any lingering app transitions form the MoveTaskToFront operation.
mFocusedStack.executeAppTransition(targetOptions);
}
...
return false;
}
// ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options){
...
result = resumeTopActivityInnerLocked(prev, options);
...
return result;
}
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
// startPausingLocked方法裏,棧頂Activity執行onPause方法退出
pausing |= startPausingLocked(userLeaving, false, next, false);
}
......
mStackSupervisor.startSpecificActivityLocked(next, true, true);
...
return true;
}
複製代碼
從重載方法resumeFocusedStackTopActivityLocked中,又調用ActivityStack類中的 resumeTopActivityUncheckedLocked方法,該方法裏調用resumeTopActivityInnerLocked方法中會去判斷是否有Activity處於Resume狀態,若是有的話會先讓這個Activity執行Pausing過程,而後再執行startSpecificActivityLocked方法啓動要啓動Activity。app
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.getStack().setLaunchTime(r);
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
// 若是不是第一次啓動直接startActivity
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 ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
if (!isolated) {
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
checkTime(startTime, "startProcess: after getProcessRecord");
...
} else {
app = null;
}
...
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
checkTime(startTime, "startProcess: done starting proc!");
return (app.pid != 0) ? app : null;
}
private final void startProcessLocked(ProcessRecord app,
String hostingType, String hostingNameStr) {
startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
null /* entryPoint */, null /* entryPointArgs */);
}
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
startProcessLocked(app, hostingType, hostingNameStr, false /* disableHiddenApiChecks */,
null /* abiOverride */, null /* entryPoint */, null /* entryPointArgs */);
}
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride,
String entryPoint, String[] entryPointArgs) {
long startTime = SystemClock.elapsedRealtime();
......// 初始化設置app
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
...
ProcessStartResult startResult;
// 指定不是webview_service
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, entryPointArgs);
} else {
// 開啓新進程,並制定這個進程的入口是 ActivityThread 的靜態方法 main
// entryPoint,由上面代碼可知 entryPoint == "android.app.ActivityThread"
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, entryPointArgs);
}
...
}
}
// Process類
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) {
// 請求 Zygote 來建立一個應用程序進程
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}
// ZygoteProcess類
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 (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,"Starting VM process through Zygote failed");
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
}
}
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>();
......
synchronized(mLock) {
// 初始化完畢
// openZygoteSocketIfNeeded(),建立一個鏈接到 Zygote 的 LocalSocket 對象
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
int sz = args.size();
for (int i = 0; i < sz; i++) {
if (args.get(i).indexOf('\n') >= 0) {
throw new ZygoteStartFailedEx("embedded newlines not allowed");
}
}
// 寫參數給Zygote
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
// 將要建立的應用程序的進程啓動參數傳到 LocalSocket 對象中
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();
Process.ProcessStartResult result = new Process.ProcessStartResult();
//等待socket服務端(即zygote)返回新建立的進程pid;
result.pid = inputStream.readInt();
result.usingWrapper = inputStream.readBoolean();
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
return result;
} catch (IOException ex) {
zygoteState.close();
throw new ZygoteStartFailedEx(ex);
}
}
private static ZygoteState openZygoteSocketIfNeeded(String abi)
throws ZygoteStartFailedEx {
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
// 向主zygote發起connect()操做
primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);
} catch (IOException ioe) {
...
}
}
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
// 當主zygote沒能匹配成功,則採用第二個zygote,發起connect()操做
secondaryZygoteState = ZygoteState.connect(SECONDARY_ZYGOTE_SOCKET);
}
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
...
}
複製代碼
system_server進程的zygoteSendArgsAndGetResult()方法經過socket向Zygote進程發送消息,這是便會喚醒Zygote進程,來響應socket客戶端的請求(即system_server端),接下來的操做即是在Zygote來建立進程,Zygote進程是由init進程而建立的,進程啓動以後調用ZygoteInit.main()->runSelectLoop-> acceptCommandPeer->runOnce->Zygote.forkAndSpecialize執行完此方法又通過一系列native以及c/c++代碼完成全部App進程的工做->handleChildProc->...->ActivityThread.main,即ActivityThread.main是程序啓動的真正入口socket
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
......
/*
* 這個app.thread的類型爲IApplicationThread,
* IApplicationThread繼承了IInterface接口,因此它是一個Binder類型的接口。
* 從IApplicationThread聲明的接口方法能夠看出,它的內部包含了
* 大量啓動、中止Activity的接口,此外還包含了啓動和中止服務的接口,從接口方法的命 * 名能夠知道,IApplicationThread這個Binder接口的實現者完成了大量和Activity以及
* Service啓動和中止相關的功能。而IApplicationThread的實現者就是
* ActivityThread中的內部類ApplicationThread。因此,繞來繞去,
* 是用ApplicationThread中的scheduleLaun*chActivity來啓動Activity的。
*/
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
......
return true;
}
複製代碼
此時走到了ApplicationThread類中(ApplicationThread類爲ActivityThread靜態內部類)的 scheduleLaunchActivity方法中,該方法使用Handler發送LAUNCH_ACTIVITY消息後,調用 handleLaunchActivity方法 -> 最終在performLaunchActivity方法中的建立並啓動Activityide
private void handleLaunchActivity(ActivityClientRecord r
, Intent customIntent, String reason) {
...
/**
* 此處有2個重點:
* 1.建立Application並回調attach、onCreate
* 2.建立Activity並回調attach、onCreate
*/
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
// 此處回調Activity的onStart和onResume方法
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
...
} else {
...
}
}
複製代碼
至此,Activity啓動完成。oop
參考文章:源碼分析
...
注:如有什麼地方闡述有誤,敬請指正。