Activity during startup source code analysis (Android 8.0)

Start the process of source code analysis Activity

Activity of this article to start the process, we are usually initiated by the target activity startActivity or startActivityForResult, then we Proceeding to start exploring the system is how to achieve the goal of the activity.

startActivity(new Intent(context, MainActivity.class));
startActivityForResult(new Intent(context, SecondActivity.class),1000);

Generally, we are starting to target activity by the above two functions, we look at the source code startActivity

Activity:

@Override
public void startActivity(Intent intent) {
    this.startActivity(intent, null);
}
@Override
public 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);
    }
}

We can actually see startActivity startActivityForResult call to start the target activity but this time requestcode -1.

Activity:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
    startActivityForResult(intent, requestCode, null);
}
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);//1调用Instrumentation.execStartActivity
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());//2发送请求结果
        }
        if (requestCode >= 0) {
            // If this start is requesting a result, we can avoid making
            // the activity visible until the result is received.  Setting
            // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
            // activity hidden during this time, to avoid flickering.
            // This can only be done when a result is requested because
            // that guarantees we will get information back when the
            // activity is finished, no matter what happens to it.
            mStartedActivity = true;
        }

        cancelInputsAndStartExitTransition(options);
        // TODO Consider clearing/flushing other event sources and events for child windows.
    } else {
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
            // Note we want to go through this method for compatibility with
            // existing applications that may have overridden it.
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}

In startActivityForResult will first call in the notes at 1 Instrumentation.execStartActivity to get a ActivityResult example, ActivityResult is used to describe the results of the implementation of the target activity. Thus we can see activity start certainly do with Instrumentation.execStartActivity. Note 2 will be called at the start ActivityThread.sendActivityResult to send out the results, which ultimately is sent through a Handler SEND_RESULT the Message, will not start detailed here are interested in their own research.
Here to explain the concept of a few categories:
ActivityThread: It's true App entrance, when App starts, will invoke its main method to begin, open the message loop queue. The legendary UI thread, that is the main thread. And ActivityManagerService cooperate together to complete the Activity of management;
Instrumentation: Each application is only one target Instrumentation, there is a reference to the object within each Activity. When Instrumentation can be understood as the steward of the application process, ActivityThread to create or open an Activity, need to carry out specific operations by Instrumentation

The following look Instrumentation.execStartActivity

Instrumentation:

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, String resultWho,
        Intent intent, int requestCode, Bundle options, UserHandle user) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    //...
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        //1 调用AMS的startActivity
        int result = ActivityManager.getService()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, resultWho,
                    requestCode, 0, null, options, user.getIdentifier());
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

1 note at the first call of the getService ActivityManager ().

ActivityManager

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;
            }
        };

getService () internally calls IActivityManagerSingleton.get (), first get a binder in AMS by ServiceManager.getService get (), and then call IActivityManager.Stub.asInterface. The role of these operations is carried out using AIDL IPC (interprocess communication) to communicate with the AMS. (Note 7.0 and previous versions of the IPC process is :( client) ActivityManagerProxy -> Binder drive -> (server) ActivityManagerService, but after 8.0 goes IPC carried out by aidl)

By ActivityManager.getService () can get AMS proxy, then call the AMS's startActivity

ActivityManagerService

public final int startActivity(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}


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) {
    enforceNotIsolatedCaller("startActivity");
    userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
            userId, false, ALLOW_FULL_ONLY, "startActivity", null);
    // TODO: Switch to user app stacks here.
    return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
}

startActivity called startActivityAsUser, startActivityAsUser they call ActivityStarter.startActivityMayWait, explain the role of the next ActivityStarter here.

ActivityStarter: Start Activity controller, it is mainly used for converting Intent activity and flags into the stack and related tasks;

ActivityStarter:

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) {
//...
//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);

//...
}



int startActivityLocked(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, String reason) {
//...

mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
        aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
        callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
        options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
        inTask);

//...
}

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) {
//...

doPendingActivityLaunchesLocked(false);

return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
        options, inTask, outActivity);

}

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {
//...
//1
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
        startFlags, doResume, options, inTask, outActivity);

//...
}


private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {
//...
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
        mOptions);
//...
}

Then through a series of calls (startActivityMayWait ---> startActivityLocked -> startActivity -> startActivity -> startActivityUnchecked -> ActivityStackSupervisor.resumeFocusedStackTopActivityLocked) in the comment at a final call startActivityLocked went ActivityStackSupervisor.resumeFocusedStackTopActivityLocked

ActivityStackSupervisor: mainly manages mHomeStack and mFocusedStack two ActivityStack and other related information;

ActivityStackSupervisor:

boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

    if (!readyToResume()) {
        return false;
    }

    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }

    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    if (r == null || r.state != RESUMED) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    } else if (r.state == RESUMED) {
        // Kick off any lingering app transitions form the MoveTaskToFront operation.
        mFocusedStack.executeAppTransition(targetOptions);
    }

    return false;
}

ResumeFocusedStackTopActivityLocked and internal calls ActivityStack.resumeTopActivityUncheckedLocked

ActivityStack: Activity in the stack of AMS management, it has already started to record the relationship Activity and status information. Whether to start a new process decided by ActivityStack

ActivityStack:

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
//...
result = resumeTopActivityInnerLocked(prev, options);
//...
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
//...
    if (mResumedActivity != null) {
        //同步等待pause当前Activity的结果
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
//...
}

From this we know that starting a new activity, you need to first current activity pause.

ActivityStack:

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean pauseImmediately) {
    //....
    //去当前Activity所在应用进程暂停当前activity。
     prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
            userLeaving, prev.configChangeFlags, pauseImmediately);
    //....
}

Prev.app.thread here actually ApplicationThread
its role is the communication between the AMS and ActivityThread, ApplicationThread itself is an internal class of ActivityThread.

ActivityThread$ApplicationThread:

public final void schedulePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, boolean dontReport) {
    int seq = getLifecycleSeq();
    if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
            + " operation received seq: " + seq);
    sendMessage(
            finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
            token,
            (userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
            configChanges,
            seq);
}

Internal transmit a message, the message is sent and processed in the class H, H is a subclass of the handler and inside it is a class of ActivityThread.

ActivityThread$H:

public void handleMessage(Message msg) {
   //...
    switch (msg.what) {
    case PAUSE_ACTIVITY:
        {
            SomeArgs args = (SomeArgs) msg.obj;
            handlePauseActivity((IBinder) args.arg1, false, (args.argi1 & USER_LEAVING) != 0,
            args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
        }
        break;
    }
    //...
}

Call handlePauseActivity method in H.

ActivityThread:

private void handlePauseActivity(IBinder token, boolean finished,
        boolean userLeaving, int configChanges, boolean dontReport, int seq) {
//...
performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");//执行pause

// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
    QueuedWork.waitToFinish();
}

// Tell the activity manager we have paused.
if (!dontReport) {
    try {
        ActivityManager.getService().activityPaused(token);//执行完后通知AMS当前Activity已经pause
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
}
}

final Bundle performPauseActivity(IBinder token, boolean finished,
        boolean saveState, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
}


final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
        boolean saveState, String reason) {
//...
// Next have the activity save its current state and managed dialogs...
if (!r.activity.mFinished && saveState) {
    callCallActivityOnSaveInstanceState(r);
}

performPauseActivityIfNeeded(r, reason);//执行pause
//...
}

private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
//...
mInstrumentation.callActivityOnPause(r.activity);
//...
}

Internal handlePauseActivity will go to perform the pause operation, AMS will be notified after the implementation. pause execution after a series of calls eventually call Instrumentation.callActivityOnPause

Instrumentation:

public void callActivityOnPause(Activity activity) {
    activity.performPause();
}

final void performPause() {
    mDoReportFullyDrawn = false;
    mFragments.dispatchPause();
    mCalled = false;
    onPause();//调用activity的生命周期函数onPause()
    mResumed = false;
    if (!mCalled && getApplicationInfo().targetSdkVersion
            >= android.os.Build.VERSION_CODES.GINGERBREAD) {
        throw new SuperNotCalledException(
                "Activity " + mComponent.toShortString() +
                " did not call through to super.onPause()");
    }
    mResumed = false;
}

So far in the current activity onPause state.

In handlePauseActivity method after the pause operation notified AMS, call ActivityManager.getService (). ActivityPaused

ActivityManagerService:

public final void activityPaused(IBinder token) {
    final long origId = Binder.clearCallingIdentity();
    synchronized(this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            stack.activityPausedLocked(token, false);//1
        }
    }
    Binder.restoreCallingIdentity(origId);
}

Call ActivityStack was activityPausedLocked at 1 comment

ActivityStack:

final void activityPausedLocked(IBinder token, boolean timeout) {
    if (DEBUG_PAUSE) Slog.v(TAG_PAUSE,
        "Activity paused: token=" + token + ", timeout=" + timeout);

    final ActivityRecord r = isInStackLocked(token);
    if (r != null) {
        mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
        if (mPausingActivity == r) {
            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
                    + (timeout ? " (due to timeout)" : " (pause complete)"));
            mService.mWindowManager.deferSurfaceLayout();
            try {
                completePauseLocked(true /* resumeNext */, null /* resumingActivity */);//1 pause完成
            } finally {
                mService.mWindowManager.continueSurfaceLayout();
            }
            return;
        }
//...
}

private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
//...
mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);

//...
}

调用StackSupervisor.resumeFocusedStackTopActivityLocked

StackSupervisor:

boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

    if (!readyToResume()) {
        return false;
    }
/如果启动Activity和要启动的Activity在同一个ActivityStack中,调用targetStack对象的方法
    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }

    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
 //如果不在同一个ActivityStack中,则调用mFocusStack对象的方法
    if (r == null || r.state != RESUMED) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    } else if (r.state == RESUMED) {
        // Kick off any lingering app transitions form the MoveTaskToFront operation.
        mFocusedStack.executeAppTransition(targetOptions);
    }

    return false;
}

ActivityStack:

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
//...
result = resumeTopActivityInnerLocked(prev, options);
//...
}


private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
//...
if (mResumedActivity != null) {
    //又回到此处 但是因为之前pause时已经将mResumedActivity置null,所以不会再次调用startPausingLocked
    pausing |= startPausingLocked(userLeaving, false, next, false);
}
//...
//启动目标activity
mStackSupervisor.startSpecificActivityLocked(next, true, true);
//...
}

The second came resumeTopActivityUncheckedLocked function, with the last difference is that the pause operation has been completed, it will come at StackSupervisor.startSpecificActivityLocked below to start the target activity.

StackSupervisor:

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
//...
realStartActivityLocked(r, app, andResume, checkConfig);

//...
}


final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
        boolean andResume, boolean checkConfig) throws RemoteException {
//...
app.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);
//...
}

We can see the end come ActivityThread.scheduleLaunchActivity

ActivityThread:

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
        ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
        CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
        int procState, Bundle state, PersistableBundle persistentState,
        List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
        boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
//...
sendMessage(H.LAUNCH_ACTIVITY, r);
}

Back to the Class H, H we look at the direct method handleMessage

ActivityThread$H:

public void handleMessage(Message msg) {
    switch (msg.what) {
        case LAUNCH_ACTIVITY: {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
            final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

            r.packageInfo = getPackageInfoNoCheck(
                    r.activityInfo.applicationInfo, r.compatInfo);
            handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        } break;
}


private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
//...
Activity a = performLaunchActivity(r, customIntent);
//...
}


private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//...
ContextImpl appContext = createBaseContextForActivity(r);//1 创建activity的BaseContext
Activity activity = null;
try {
    java.lang.ClassLoader cl = appContext.getClassLoader();
    activity = mInstrumentation.newActivity(
            cl, component.getClassName(), r.intent);//2 创建activity
    StrictMode.incrementExpectedActivityCount(activity.getClass());
    r.intent.setExtrasClassLoader(cl);
    r.intent.prepareToEnterProcess();
    if (r.state != null) {
        r.state.setClassLoader(cl);
    }
}
//...
Application app = r.packageInfo.makeApplication(false, mInstrumentation);//3 创建Application
//...
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);//4 调用attach
//...
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);//5 调用生命周期函数OnCreate
//...
}

H after receiving the message called handleLaunchActivity method, which is quite important to our analysis under useful information.
First created in Note 1 at the BaseContext activity, the specific details of the reference Contex Detailed knowledge
at the comments by two Instrumentation instance is constructed activity, specifically, by the ClassLoader go newInstance to create.
Notes Application acquired at the three current applications should be noted that if the current application has not been created then Application This creates Application and return, if you've created will return to Application has been created.
Note 4 attach call
annotation 5 is used for the life cycle of a callback function OnCreate, the specific process is as follows:

Instrumentation:

public void callActivityOnCreate(Activity activity, Bundle icicle,
        PersistableBundle persistentState) {
    prePerformCreate(activity);
    activity.performCreate(icicle, persistentState);//1
    postPerformCreate(activity);
}


final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    mCanEnterPictureInPicture = true;
    restoreHasCurrentPermissionRequest(icicle);
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        onCreate(icicle);//回调onCreate
    }
    mActivityTransitionState.readState(icicle);

    mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
            com.android.internal.R.styleable.Window_windowNoDisplay, false);
    mFragments.dispatchActivityCreated();
    mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
}

At this point the target activity started done, we can do the appropriate initialization operation in the onCreate.

Throughout the entire process can be seen, after several calls to start the process involves a lot of class and the entire process is also very complex and cumbersome, so we need to summarize After evaluating the process, which can help us from the macro to the overall process understanding more profound.

First, let's look back at the whole process involved in the class and its role:

  • Instrumentation: Each application has only one target Instrumentation, there is a reference to the object within each Activity. When Instrumentation can be understood as the steward of the application process, ActivityThread to create or suspend an Activity, need to carry out specific operations by Instrumentation.

  • ActivityManagerService: one of the core services in Android, is responsible for the system to start the four components, switches, scheduling and management and scheduling applications, etc.

  • ActivityManager: This class provides the Activity, Service and Process related information and interactive methods, it can be seen as the auxiliary class ActivityManagerService

  • ActivityThread: App of the real entrance, when App starts, it calls its main method to begin, open the message loop queue. The legendary UI thread, that is the main thread. And ActivityManagerService with complete Activity management work together;

  • ApplicationThread: to achieve the interaction between ActivityManagerService and ActivityThread. In ActivityManagerService need to manage the life cycle of Activity in the relevant Application by ApplicationThread proxy object and ActivityThread communication;

  • ActvitityStack: Activity in the stack of AMS management, it has already started to record the relationship Activity and status information. By ActivityStack decide whether to start a new process;

  • ActivityRecord: ActivityStatck managed objects, each Activity in a ActivityRecord AMS corresponding to the recording state and other information Activity. Activity Activity can be understood as the mapping of the object in the server;

  • TaskRecord: AMS abstract concept out of the task stack. A TaskRecord contains several ActivityRecord. ASM use it to ensure Activity start and exit order. It is directly related to the startup mode of Activity.

  • ActivityStarter: Start Activity controller, it is mainly used for converting Intent activity and flags into the stack and related tasks;

  • ActivityStackSupervisor: Activity is responsible for all management stack. The internal management of the mHomeStack, mFocusedStack and mLastFocusedStack three Activity stack. Which, mHomeStack management is associated Activity Launcher stack; mFocusedStack management is currently displayed in the foreground Activity Activity stack; mLastFocusedStack management is on display in a foreground Activity Activity stack.

For the above categories we should be familiar with its role.

The next step is to start the process summarized :( B as an example here to start A)
1, the Activity function A starts by startActivity like B
2, after the step of the current application sends a call to a B interprocess communication request the Activity to start the AMS;
3, AMS will save component information to start Activity B down, ActivityManagerService received a request to start after the necessary initialization and refresh state, and then parse Activity startup mode, do a series of preparations for the start Activity.

4, and then determines whether the stack is empty, if not empty i.e. Activity A currently displayed in the foreground, will be the first stack of Activity onPause process, this process is performed by the communication Binder (ApplicationThread and Interface Definition Language)
5 after activity a pause operation is completed, notifies the communication Binder by AMS (ActivityManagerService and Interface Definition language), may be performed to start the operation of the activity B (stored activity information to start the top of the stack) (note here that if Activity is initiated through the direct implementation of onRestart-> onStart-> onResume process started directly Activity (warm start). otherwise, perform a cold boot process where the application of Activity the process is a cold start of a new process by Zygote process fork and then do ActivityThread main method starts new processes)
. 6, the AMS starts performing a series of operations Activity B after the above steps, and cross-process communication calls through Binder (ApplicationThread and Interface Definition language), starts Activity B;

Reference:
Android Activity start the process (based on Android8.0 system)
Activity start the process source code analysis
Activity startup process is simply insane!
Activity start the process of full resolution

Guess you like

Origin www.cnblogs.com/Robin132929/p/12166563.html