Activity的启动过程(源码API27)
Oreo -> Android8.1 -> API level 27
啟動activity的方式有以下幾種:
- 1、在應用程序中startActivity()或startActivityForResult()啟動指定activity
- 2、在launcher中單擊應用圖標,啟動新的activity
- 3、按BACK鍵結束當前activity,自動啟動上一個activity
- 4、長按Home鍵,顯示出當前任務列表,從中選擇一個啟動。
第2、3、4種方式最終都會走到第一種方式,startActivity()又會走到startActivityForResult()。
Launcher啟動Activity
Zygote進程孵化出的第一個App進程是Launcher,這是用戶看到的桌面App。我們打開LauncherActivity看下,其實也是通過intent來啟動一個App。也就是說和第一種方式是一模一樣的。
public abstract class LauncherActivity extends ListActivity {@Overrideprotected void onListItemClick(ListView l, View v, int position, long id) {Intent intent = intentForPosition(position);startActivity(intent);} } 復制代碼Activity#startActivity()
@Overridepublic void startActivity(Intent intent) {this.startActivity(intent, null);}@Overridepublic void startActivity(Intent intent, @Nullable Bundle options) {if (options != null) {startActivityForResult(intent, -1, options);} else {// Note we want to go through this call for compatibility with// applications that may have overridden the method.startActivityForResult(intent, -1);}} 復制代碼Activity#startActivityForResult()
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {startActivityForResult(intent, requestCode, null);}public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {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());}} 復制代碼Instrumentation#execStartActivity()
mInstrumentation是一個Instrumentation對象,在Activity#attach()通過參數傳遞過來。mInstrumentation是在Application初始化的過程中實例化的。詳情可以見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);public Instrumentation getInstrumentation() {return mInstrumentation;} 復制代碼Instrumentation#execStartActivity()
ActivityManager.getService()通過Binder機制獲得AMS的實例,然后跨進度調度AMS.startActivity()
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {IApplicationThread whoThread = (IApplicationThread) contextThread; //ApplicationThread對象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;} 復制代碼ActivityManagerService#startActivity
@Overridepublic int startActivity(IBinder whoThread, String callingPackage,Intent intent, String resolvedType, Bundle bOptions) {appThread = IApplicationThread.Stub.asInterface(whoThread);return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,resolvedType, null, null, null, null, 0, 0, null, null,null, bOptions, false, callingUser, tr, "AppTaskImpl");} 復制代碼ActivityStarter#startActivityMayWait()
final int startActivityMayWait(IApplicationThread caller, int callingUid, xxxxx....) {final ActivityRecord[] outRecord = new ActivityRecord[1];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);return res;}} 復制代碼ActivityStarter#startActivityLocked()
int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent, xxx.....) {mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,inTask);return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;} 復制代碼ActivityStarter#startActivity()
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,String callingPackage, int realCallingPid, int realCallingUid, int startFlags,ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,ActivityRecord[] outActivity, TaskRecord inTask) {return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,options, inTask, outActivity);} 復制代碼ActivityStarter#startAcitity()
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 {result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,startFlags, doResume, options, inTask, outActivity);} return result;} 復制代碼ActivityStarter#startActivityUnchecked()
// Note: This method should only be called from {@link startActivity}.private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity) {mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,mOptions);return START_SUCCESS;} 復制代碼ActivityStack#startActivityLocked()
final void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,boolean newTask, boolean keepCurTransition, ActivityOptions options) {ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);} 復制代碼ActivityStack#ensureActivitiesVisibleLocked()
final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,boolean preserveWindows) {if (r.app == null || r.app.thread == null) {if (makeVisibleAndRestartIfNeeded(starting, configChanges, isTop,resumeNextActivity, r)) {}} } 復制代碼ActivityStack#makeVisibleAndRestartIfNeeded()
private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,boolean isTop, boolean andResume, ActivityRecord r) {if (isTop || !r.visible) {if (r != starting) {mStackSupervisor.startSpecificActivityLocked(r, andResume, false);return true;}}return false;} 復制代碼ActivityStackSupervisor#startSpecificActivityLocked()
- 這里兵分兩路, if (app != null && app.thread != null) -> realStartActivityLocked() -> scheduleLaunchActivity,//app.thread是一個IApplicationThread對象,也就是說回調了ApplicationThread里的scheduleLaunchActivity
否則的話,mService.startProcessLocked(),mService是AMS對象,是在ActivityStackSupervisor構造函數里賦值的。
final ActivityManagerService mService;void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {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);}// 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);}final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException {//app.thread是一個IApplicationThread對象,也就是說回調了ApplicationThread里的scheduleLaunchActivityapp.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,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, !andResume,mService.isNextTransitionForward(), profilerInfo);} 復制代碼ActivityManagerService#startProcessLocked()
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 */);} 復制代碼ActivityManagerService#startProcessLocked()
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) {startProcessLocked(app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);return (app.pid != 0) ? app : null;} 復制代碼ActivityManagerService#startProcessLocked()
private final void startProcessLocked(ProcessRecord app, String hostingType,String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {ProcessStartResult startResult;if (hostingType.equals("webview_service")) {startResult = startWebView(entryPoint,app.processName, uid, uid, gids, debugFlags, mountExternal,app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, null, entryPointArgs);} else {startResult = Process.start(entryPoint,app.processName, uid, uid, gids, debugFlags, mountExternal,app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, invokeWith, entryPointArgs);}} 復制代碼Process#start()
public static final ProcessStartResult start(final String processClass,final String niceName,int uid, int gid, int[] gids,int debugFlags, int mountExternal,int targetSdkVersion,String seInfo,String abi,String instructionSet,String appDataDir,String invokeWith,String[] zygoteArgs) {return zygoteProcess.start(processClass, niceName, uid, gid, gids,debugFlags, mountExternal, targetSdkVersion, seInfo,abi, instructionSet, appDataDir, invokeWith, zygoteArgs);} 復制代碼ZygoteProcess#start()
public final Process.ProcessStartResult start(final String processClass,final String niceName,int uid, int gid, int[] gids,int debugFlags, int mountExternal,int targetSdkVersion,String seInfo,String abi,String instructionSet,String appDataDir,String invokeWith,String[] zygoteArgs) {try {return startViaZygote(processClass, niceName, uid, gid, gids,debugFlags, mountExternal, targetSdkVersion, seInfo,abi, instructionSet, appDataDir, invokeWith, zygoteArgs);} catch (ZygoteStartFailedEx ex) {Log.e(LOG_TAG,"Starting VM process through Zygote failed");throw new RuntimeException("Starting VM process through Zygote failed", ex);}} 復制代碼ZygoteProcess#startViaZygote()
private Process.ProcessStartResult startViaZygote(final String processClass,final String niceName,final int uid, final int gid,final int[] gids,int debugFlags, int mountExternal,int targetSdkVersion,String seInfo,String abi,String instructionSet,String appDataDir,String invokeWith,String[] extraArgs)throws ZygoteStartFailedEx {ArrayList<String> argsForZygote = new ArrayList<String>();// --runtime-args, --setuid=, --setgid=,// and --setgroups= must go firstargsForZygote.add("--runtime-args");argsForZygote.add("--setuid=" + uid);argsForZygote.add("--setgid=" + gid);//省略argsForZygote的各種參數配置synchronized(mLock) {return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);}} 復制代碼ZygoteProcess#zygoteSendArgsAndGetResult()
啟動一個新的進程
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(ZygoteState zygoteState, ArrayList<String> args)throws ZygoteStartFailedEx {try {int sz = args.size();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();result.pid = inputStream.readInt();result.usingWrapper = inputStream.readBoolean();return result;} catch (IOException ex) {zygoteState.close();throw new ZygoteStartFailedEx(ex);}} 復制代碼總結
Activity的啟動是通過AMS來調度的,和application的啟動過程類似,通過Binder機制和AMS通訊,Ams又回調IApplicationThread中的方法,由mH發出一個Message,并進行處理。
Process的啟動是通過zygote來啟動的。
中間的很多細節也沒太研究。
轉載于:https://juejin.im/post/5b65599b5188251b3a1deab6
總結
以上是生活随笔為你收集整理的Activity的启动过程(源码API27)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于props的注意事项!
- 下一篇: ArcGIS 基础11-专题制图