Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities
The startup process needs to be combined with the Application. Juejin. Cn/post / 701209…
/ / check to see if the top visible activities are waiting for the if (normalMode) {try {the if (mStackSupervisor. AttachApplicationLocked (app)) {didSomething = true; } } catch (Exception e) { Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); badApp = true; }}Copy the code
Enter ActivityStackSupervisor
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { final String processName = app.processName; boolean didSomething = false; for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx); for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = display.getChildAt(stackNdx); if (! isFocusedStack(stack)) { continue; } // Add all activities from activityStack (Activity stack) to mTmpActivityList stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList); / / returns the current application of the top of the activity final ActivityRecord top = stack. TopRunningActivityLocked (); final int size = mTmpActivityList.size(); For (int I = 0; i < size; i++) { final ActivityRecord activity = mTmpActivityList.get(i); f (activity.app == null && app.uid == activity.info.applicationInfo.uid && processName.equals(activity.processName)) { try { if (realStartActivityLocked(activity, app, top == activity /* andResume */, true /* checkConfig */)) { didSomething = true; } } catch (RemoteException e) { throw e; } } } } } if (! didSomething) { ensureActivitiesVisibleLocked(null, 0, ! PRESERVE_WINDOWS); } return didSomething; }Copy the code
Enter the realStartActivityLocked method
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { ... ClientTransaction = ClientTransaction. Obtain (app.thread, r.aptoken); / / add the callback clientTransaction. AddCallback (LaunchActivityItem. Obtain (new Intent (r.i ntent), System. IdentityHashCode (r), r.info, mergedConfiguration.getGlobalConfiguration(), mergedConfiguration.getOverrideConfiguration(), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, mService.isNextTransitionForward(), profilerInfo)); final ActivityLifecycleItem lifecycleItem; if (andResume) { lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward()); } else { lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); / / to commit the transaction mService. GetLifecycleManager () scheduleTransaction (clientTransaction); . }Copy the code
Enter the ClientLifecycleManager
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
// If client is not an instance of Binder - it's a remote call and at this point it is
// safe to recycle the object. All objects used for local calls will be recycled after
// the transaction is executed on client in ActivityThread.
transaction.recycle();
}
}
Copy the code
Enter the Schedule method of the ClientTransaction class
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
Copy the code
The mClient is actually the IApplicationThread
public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
if (instance == null) {
instance = new ClientTransaction();
}
instance.mClient = client;
instance.mActivityToken = activityToken;
return instance;
}
Copy the code
Return to the scheduleTransaction method in ActivityThread
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
Copy the code
Enter the ActivityThread parent class ClientTransactionHandler
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
Copy the code
Go back to the handlerMessage in activityThread
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
Copy the code
Enter the TransactionExecutor class and execute the execute method
public void execute(ClientTransaction transaction) {
final IBinder token = transaction.getActivityToken();
log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
executeCallbacks(transaction);
executeLifecycleState(transaction);
mPendingActions.clear();
log("End resolving transaction");
}
Copy the code
Go to the executeCallbacks method
public void executeCallbacks(ClientTransaction transaction) { final List<ClientTransactionItem> callbacks = transaction.getCallbacks(); if (callbacks == null) { // No callbacks to execute, return early. return; } log("Resolving callbacks"); final IBinder token = transaction.getActivityToken(); ActivityClientRecord r = mTransactionHandler.getActivityClient(token); // In case when post-execution state of the last callback matches the final state requested // for the activity in this transaction, we won't do the last transition here and do it when // moving to final state instead (because it may contain additional parameters from server). final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest(); final int finalState = finalStateRequest ! = null ? finalStateRequest.getTargetState() : UNDEFINED; // Index of the last callback that requests some post-execution state. final int lastCallbackRequestingState = lastCallbackRequestingState(transaction); Final int size = callbacks.size(); for (int i = 0; i < size; ++ I) {// Get LaunchActivityItem final ClientTransactionItem item = callbacks.get(I); log("Resolving callback: " + item); final int postExecutionState = item.getPostExecutionState(); final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r, item.getPostExecutionState()); if (closestPreExecutionState ! = UNDEFINED) { cycleToPath(r, closestPreExecutionState); } // Perform the form creation request item.execute(mTransactionHandler, token, mPendingActions); item.postExecute(mTransactionHandler, token, mPendingActions); if (r == null) { // Launch activity request will create an activity record. r = mTransactionHandler.getActivityClient(token); } if (postExecutionState ! = UNDEFINED && r ! = null) { // Skip the very last transition and perform it by explicit state request instead. final boolean shouldExcludeLastTransition = i == lastCallbackRequestingState && finalState == postExecutionState; cycleToPath(r, postExecutionState, shouldExcludeLastTransition); }}}Copy the code
Go to the Execute method on the LaunchActivityItem
@Override public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); // Create an ActivityClientRecord object, ActivityClientRecord r = new ActivityClientRecord(Token, mIntent, mIdent, mInfo, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState, mPendingResults, mPendingNewIntents, mIsForward, mProfilerInfo, client); / / callback to activityThread client. HandleLaunchActivity (r, pendingActions, null customIntent / * * /); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); }Copy the code
Go back to the handleLaunchActivity method in the activityThread class
public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) { ... Final Activity A = performLaunchActivity(r, customIntent); . }Copy the code
Enter the performLaunchActivity method
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ... Try {/ / by reflecting Java objects created activity. Lang. This cl = appContext. GetClassLoader (); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); r.intent.prepareToEnterProcess(); if (r.state ! = null) { r.state.setClassLoader(cl); } } catch (Exception e) { if (! mInstrumentation.onException(activity, e)) { throw new RuntimeException( "Unable to instantiate activity " + component + ": " + e.toString(), e); }}... }Copy the code
Enter the newActivity method in the Instrumentation class
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); }Copy the code
Enter the AppComponentFactory class
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
@Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Activity) cl.loadClass(className).newInstance();
}
Copy the code
At this point, the activity is created. Continue back to the activityThread class
activity.mCalled = false; If (r.i sPersistable ()) {/ / call the activity lifecycle method through mInstrumentation mInstrumentation. CallActivityOnCreate (activity, r.s Tate, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); }Copy the code
Enter the callActivityOnCreate method in the Instrumentation class
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);
postPerformCreate(activity);
}
Copy the code
Enter the performCreate method in the activity
final void performCreate(Bundle icicle, PersistableBundle persistentState) { mCanEnterPictureInPicture = true; restoreHasCurrentPermissionRequest(icicle); if (persistentState ! = null) { onCreate(icicle, persistentState); } else { onCreate(icicle); } writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate"); mActivityTransitionState.readState(icicle); mVisibleFromClient = ! mWindow.getWindowStyle().getBoolean( com.android.internal.R.styleable.Window_windowNoDisplay, false); mFragments.dispatchActivityCreated(); mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions()); }Copy the code
The general startup flow chart is as follows: