本篇爲雞生蛋系列第三篇文章java
startActivity()流程極其複雜,代碼龐大,牽扯到的類等也較多,
這裏簡單講下流程, 更多的做爲我的學習筆記。android
點擊Launcher圖標後,Launcher也是經過startActivity()啓動另外一應用的,
Launcher自己流程不分析了。web
AMS Android9.0
http://androidxref.com/9.0.0_r3/segmentfault
參考:
Android應用程序的Activity啓動過程簡要介紹和學習計劃
https://blog.csdn.net/luoshen...
Android深刻四大組件(六)Android8.0 根Activity啓動過程(前篇)
https://blog.csdn.net/itachi8...app
問題
ActivityStartController ActivityStarter 是什麼?做用?關係?ide
frameworks/base/services/java/com/android/server/SystemServer.java private void startBootstrapServices() { ...... mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer);
frameworks/base/core/java/android/app/ContextImpl.java
有幾個方法可startActivity(), 最終都調到ActivityManagerService.java裏
eg:函數
startActivity() --> mMainThread.getInstrumentation().execStartActivity() --> startActivity()/ActivityManagerService.java --> startActivityAsUser() startActivityAsUser() --> ... startActivityAsUser()/ActivityManagerService.java
startActivityAsUser()/ActivityManagerService.java 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) { //判斷調用者進程是否被隔離 enforceNotIsolatedCaller("startActivity"); userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser"); // TODO: Switch to user app stacks here. 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(); }
這裏經過 ActivityStartController 申請了個 ActivityStarter,而後執行
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.javaoop
maywait由上面setMayWait(userId)設置, 而後調用 startActivityMayWait() 或者 startActivity()
執行完後onExecutionComplete()回調ActivityStartController的 onExecutionComplete()執行一些回收任務;post
/** * Starts an activity based on the request parameters provided earlier. * @return The starter result. */ int execute() { try { // TODO(b/64750076): Look into passing request directly to these methods to allow // for transactional diffs and preprocessing. if (mRequest.mayWait) { return startActivityMayWait(mRequest.caller, mRequest.callingUid, mRequest.callingPackage, mRequest.intent, mRequest.resolvedType, mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo, mRequest.resultWho, mRequest.requestCode, mRequest.startFlags, mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig, mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId, mRequest.inTask, mRequest.reason, mRequest.allowPendingRemoteAnimationRegistryLookup); } else { return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent, mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo, ...... } } finally { onExecutionComplete(); } private 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, SafeActivityOptions options, boolean ignoreTargetSecurity, int userId, TaskRecord inTask, String reason, boolean allowPendingRemoteAnimationRegistryLookup) { ...... final ActivityRecord[] outRecord = new ActivityRecord[1]; int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason, allowPendingRemoteAnimationRegistryLookup); ...... if (outResult != null) { outResult.result = res; final ActivityRecord r = outRecord[0]; // 根據返回結果進一步處理 switch(res) { case START_SUCCESS: { ...... case START_DELIVERED_TO_TOP: { ...... case START_TASK_TO_FRONT: { ......
上面的caller爲IApplicationThread
startActivity(IApplicationThread..)也有兩個,最終調用到了startActivity(final ActivityRecord r..)學習
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, ...... //建立即將要啓動的Activity的描述類ActivityRecord ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid, callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, mSupervisor, checkedOptions, sourceRecord); ...... return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask, outActivity); }
startActivity(IApplicationThread..) --> startActivity(final ActivityRecord r..) 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(); result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity); } finally { ...... } postStartActivityProcessing(r, result, mTargetStack); return result; } private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { ...... if (reusedActivity != null) { ...... reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity); ....... // 註釋1 是否要建立新的task // Should this be considered a new task? int result = START_SUCCESS; if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { newTask = true; // 註釋2 result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack); } else if (mSourceRecord != null) { result = setTaskFromSourceRecord(); } else if (mInTask != null) { result = setTaskFromInTask(); } else { // This not being started from an existing activity, and not part of a new task... // just put it in the top task, though these days this case should never happen. setTaskToCurrentTopOrCreateNewTask(); } ...... mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition, mOptions); if (mDoResume) { final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked(); if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) { ... mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); // Go ahead and tell window manager to execute app transition for this activity // since the app transition will not be triggered through the resume channel. mService.mWindowManager.executeAppTransition(); } else { // If the target stack was not previously focusable (previous top running activity // on that stack was not visible) then any prior calls to move the stack to the // will not update the focused stack. If starting the new activity now allows the // task stack to be focusable, then ensure that we now update the focused stack // accordingly. if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) { mTargetStack.moveToFront("startActivityUnchecked"); } mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions); } } else if (mStartActivity != null) { mSupervisor.mRecentTasks.add(mStartActivity.getTask()); } mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack); mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode, preferredLaunchDisplayId, mTargetStack); return START_SUCCESS; }
在註釋1處咱們得知,啓動根Activity時會將Intent的Flag設置爲FLAG_ACTIVITY_NEW_TASK,
這樣註釋1處的條件判斷就會知足,
接着執行註釋2處的 setTaskFromReuseOrCreateNewTask(),其內部會建立一個新的TaskRecord,
TaskRecord用來描述一個Activity任務棧,也就是說setTaskFromReuseOrCreateNewTask()內部會建立一個新的Activity任務棧
boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { ...... if (targetStack != null && isFocusedStack(targetStack)) { return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); } ......// 註釋1 獲取要啓動的Activity所在棧的棧頂的不是處於中止狀態的ActivityRecord final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); if (r == null || !r.isState(RESUMED)) {// 註釋2 mFocusedStack.resumeTopActivityUncheckedLocked(null, null);// 註釋3 } else if (r.isState(RESUMED)) { // Kick off any lingering app transitions form the MoveTaskToFront operation. mFocusedStack.executeAppTransition(targetOptions); }
註釋1處調用ActivityStack的topRunningActivityLocked方法獲取要啓動的Activity所在棧的棧頂的不是處於中止狀態的ActivityRecord。
註釋2處若是ActivityRecord不爲null,或者要啓動的Activity的狀態不是RESUMED狀態,
就會調用註釋3處的ActivityStack的resumeTopActivityUncheckedLocked方法,對於即將要啓動的Activity,
註釋2的條件判斷是確定知足,所以咱們來查看ActivityStack的resumeTopActivityUncheckedLocked方法
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java mFocusedStack.resumeTopActivityUncheckedLocked() --> resumeTopActivityInnerLocked() --> mStackSupervisor.startSpecificActivityLocked(next, true, false); frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java 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) { ......//若是app已經運行,調用realStartActivityLocked() realStartActivityLocked(r, app, andResume, checkConfig); return; ...... } //若是沒有運行則調用AMS的startProcessLocked() mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); }
realStartActivityLocked()爲應用程序內部啓動非默認Activity的過程,暫時不看,
咱們看 startProcessLocked(),
startProcessLocked()函數也有好幾個, 最終都會轉爲 startProcessLocked(ProcessRecord app...
ProcessRecord生成eg:
final ProcessRecord r = new ProcessRecord(this, stats, info, proc, uid);
而後進一步的調用
startProcessLocked(String hostingType,... --> startProcess(app.hostingType... private ProcessStartResult startProcess(String hostingType, String entryPoint, ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal, ...... 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}); }
若是hostingType爲webview_service調用Process.startWebView()
不然 Process.start()
frameworks/base/core/java/android/os/Process.java * @param processClass The class to use as the process's main entry * point. public static final ProcessStartResult start(final String processClass, final String niceName, int uid, int gid, int[] gids, int runtimeFlags, int mountExternal, int targetSdkVersion, ......) { // 注意 processClass 爲 "android.app.ActivityThread" return zygoteProcess.start(processClass, niceName, uid, gid, gids, runtimeFlags, mountExternal, targetSdkVersion, seInfo, abi, instructionSet, appDataDir, invokeWith, zygoteArgs); }
咱們重點關注下傳入的參數 processClass,即 entryPoint,經過查找傳傳下來的參數,即爲
final String entryPoint = "android.app.ActivityThread";
新的進程會導入android.app.ActivityThread類,而且執行它的main函數.
zygoteProcess.start()後面有機會再分析,咱們就直接看 ActivityThread main()
frameworks/base/core/java/android/app/ActivityThread.java public static void main(String[] args) { ...... Looper.prepareMainLooper(); // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line. // It will be in the format "seq=114" 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 thread = new ActivityThread(); thread.attach(false, startSeq); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } ...... Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
其main函數主要爲Looper準備主looper, 建立一個ActivityThread實例,而後調用它的attach函數,
接着就進入消息循環了,若loope退出則拋個異常。
attach()若是爲非system則進一步調用AMS attachApplication()
private void attach(boolean system, long startSeq) { ...... if (!system) { final IActivityManager mgr = ActivityManager.getService(); try { mgr.attachApplication(mAppThread, startSeq); attachApplication()--> attachApplicationLocked() private final boolean attachApplicationLocked(IApplicationThread thread, int pid, int callingUid, long startSeq) { } else if (app.instr != null) { thread.bindApplication(processName, appInfo, providers, .. // See if the top visible activity is waiting to run in this process... if (normalMode) { try { if (mStackSupervisor.attachApplicationLocked(app)) {
thread.bindApplication() 將應用進程的ApplicationThread對象綁定到ActivityManagerService,
也就是說得到ApplicationThread對象的代理對象。
mStackSupervisor.attachApplicationLocked(app) frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java# boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { ...... final ActivityRecord top = stack.topRunningActivityLocked(); final int size = mTmpActivityList.size(); for (int i = 0; i < size; i++) { final ActivityRecord activity = mTmpActivityList.get(i); if (activity.app == null && app.uid == activity.info.applicationInfo.uid && processName.equals(activity.processName)) { try { if (realStartActivityLocked(activity, app, top == activity /* andResume */, true /* checkConfig */)) { ...... } 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), <----注意這個callback,爲LaunchActivityItem System.identityHashCode(r), r.info, ....... // Schedule transaction. mService.getLifecycleManager().scheduleTransaction(clientTransaction);
Android9引入了ClientLifecycle和ClientTransactionHandler來輔助管理Activity生命週期,過程更麻煩了.
frameworks/base/services/core/java/com/android/server/am/ClientLifecycleManager.java void scheduleTransaction(ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient(); transaction.schedule(); --> frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java private IApplicationThread mClient; public void schedule() throws RemoteException { mClient.scheduleTransaction(this); --> } frameworks/base/core/java/android/app/ActivityThread.java private class ApplicationThread extends IApplicationThread.Stub { ...... @Override public void scheduleTransaction(ClientTransaction transaction) throws RemoteException { ActivityThread.this.scheduleTransaction(transaction); --> }
ActivityThread類中並無定義scheduleTransaction方法,因此調用的是他父類ClientTransactionHandler的 scheduleTransaction()。
frameworks/base/core/java/android/app/ClientTransactionHandler.java void scheduleTransaction(ClientTransaction transaction) { transaction.preExecute(this); sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); }
Handler接到後
frameworks/base/core/java/android/app/ActivityThread.java public void handleMessage(Message msg) { case EXECUTE_TRANSACTION: final ClientTransaction transaction = (ClientTransaction) msg.obj; mTransactionExecutor.execute(transaction); --> frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java public void execute(ClientTransaction transaction) { ...... executeCallbacks(transaction); executeLifecycleState(transaction);
上面會執行callback函數,而後再執行executeLifecycleState()
這裏咱們只看callback函數,注意
realStartActivityLocked()傳入的callback爲LaunchActivityItem
public void executeCallbacks(ClientTransaction transaction) { final List<ClientTransactionItem> callbacks = transaction.getCallbacks(); ...... final int size = callbacks.size(); for (int i = 0; i < size; ++i) { final ClientTransactionItem item = callbacks.get(i); ...... item.execute(mTransactionHandler, token, mPendingActions); --> item.postExecute(mTransactionHandler, token, mPendingActions); ...... }
item.execute() 即調用到LaunchActivityItem.execute()
frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java execute() --> client.handleLaunchActivity --> ActivityThread.java handleLaunchActivity() --> performLaunchActivity()
在ActivityThread.performLaunchActivity方法中首先對Activity的ComponentName、ContextImpl、Activity
以及Application對象進行了初始化並相互關聯,
而後設置Activity主題,最後調用Instrumentation.callActivityOnCreate方法。
/** Core implementation of activity launch. */ private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ......//初始化ComponentName ComponentName component = r.intent.getComponent(); if (component == null) { component = r.intent.resolveActivity( mInitialApplication.getPackageManager()); r.intent.setComponent(component); } if (r.activityInfo.targetActivity != null) { component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity); } //初始化ContextImpl ContextImpl appContext = createBaseContextForActivity(r); Activity activity = null; try { java.lang.ClassLoader cl = appContext.getClassLoader(); //初始化activity activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); ...... } try {//初始化Application Application app = r.packageInfo.makeApplication(false, mInstrumentation); ...... if (activity != null) { ....... //關聯 appContext.setOuterContext(activity); 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); ......//調用callActivityOnCreate if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } ...... } //狀態設爲ON_CREATE r.setState(ON_CREATE); ...... return activity; }
mInstrumentation.callActivityOnCreate() --> activity.performCreate --> frameworks/base/core/java/android/app/Activity.java final void performCreate(Bundle icicle, PersistableBundle persistentState) { ...... if (persistentState != null) { onCreate(icicle, persistentState); } else { onCreate(icicle); } ...... }
即最終調用到了咱們的應用程序的onCreate()
流程圖,打開
https://www.websequencediagra...
而後複製粘貼下面的內容
Title Androd9 startActivity->OnCreate流程 participant ContextImpl participant Instrumentation participant ActivityManagerService participant ActivityStartController participant ActivityStarter participant ActivityStack participant ActivityStackSupervisor participant Process participant zygoteProcess participant ActivityThread opt startActivity part1 ContextImpl->+Instrumentation:startActivity() --> mMainThread.getInstrumentation() Instrumentation->ActivityManagerService:execStartActivity() ActivityManagerService->ActivityStartController:startActivityAsUser() ActivityStartController->ActivityStarter:obtainStarter() ActivityStarter->ActivityStarter:execute() ActivityStarter->ActivityStarter:startActivityMayWait()/startActivity(IApplicationThread...) ActivityStarter->ActivityStarter:startActivity(IApplicationThread...) ActivityStarter->ActivityStarter:startActivity(ActivityRecord...) ActivityStarter->+ActivityStarter:startActivityUnchecked(ActivityRecord...) ActivityStarter->ActivityStarter:setTaskFromReuseOrCreateNewTask() ActivityStarter->ActivityStackSupervisor:resumeFocusedStackTopActivityLocked() ActivityStackSupervisor->ActivityStack:resumeTopActivityInnerLocked() ActivityStack->ActivityStackSupervisor:startSpecificActivityLocked() alt if (app.thread != null) ActivityStackSupervisor->ActivityStackSupervisor:realStartActivityLocked() else ActivityStackSupervisor->ActivityManagerService:startProcessLocked() end ActivityManagerService->ActivityManagerService:startProcessLocked(ProcessRecord app... ActivityManagerService->ActivityManagerService:startProcessLocked(String hostingType,... ActivityManagerService->ActivityManagerService:startProcess(app.hostingType... alt 若是hostingType爲webview_service ActivityManagerService->Process:startWebView() else ActivityManagerService->Process:start("android.app.ActivityThread"...) end end opt startActivity part2 Process->zygoteProcess:start() zygoteProcess->ActivityThread:...->android.app.ActivityThread main() note right of ActivityThread Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false, startSeq); Looper.loop(); end note end