StartActivity startup step parsing, startactivity step
1. Activity. startActivity
Generally, the startActivity method can be called directly in an Activity during development, because the startActivity method is defined in the Context, and the Acitivty inherits the Context. The specific implementation of startActivity is in ContextImpl:
@Override public void startActivity(Intent intent) { warnIfCallingFromSystemProcess(); startActivity(intent, null); } @Override public void startActivity(Intent intent, Bundle options) { warnIfCallingFromSystemProcess(); // Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is // generally not allowed, except if the caller specifies the task id the activity should // be launched in. if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && options != null && ActivityOptions.fromBundle(options).getLaunchTaskId() == -1) { throw new AndroidRuntimeException( "Calling startActivity() from outside of an Activity " + " context requires the FLAG_ACTIVITY_NEW_TASK flag." + " Is this really what you want?"); } mMainThread.getInstrumentation().execStartActivity( getOuterContext(), mMainThread.getApplicationThread(), null, (Activity) null, intent, -1, options); }
2. execStartActivity
In the StartActivity method, you can see that the execStartActivity method is called. The method is in the Instrumentation:
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); } if (mActivityMonitors != null) { synchronized (mSync) { final int N = mActivityMonitors.size(); for (int i=0; i
= 0 ? am.getResult() : null; } break; } } } } try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(who); int result = ActivityManagerNative.getDefault() .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; }
3. ActivityManagerProxy. startActivity
The execStartActivity method has the following sentence:
ActivityManagerNative. getDefault (). startActivity (... omitting the specific parameter ...);
ActivityManagerNative inherits the Binder and IActivityManager interfaces,
Let's take a look at its inheritance relationship:
This is a bit similar to AIDL.
Let's take a look at the getDefault method.
static public IActivityManager getDefault() { return gDefault.get(); } private static final Singleton
gDefault = new Singleton
() { protected IActivityManager create() { IBinder b = ServiceManager.getService("activity"); if (false) { Log.v("ActivityManager", "default service binder = " + b); } IActivityManager am = asInterface(b); if (false) { Log.v("ActivityManager", "default service = " + am); } return am; } };
AcitivtyManagerService inherits ActivityManagerNative. the registered name in ServiceManager is "activity", so ServiceManager. getService ("activity"); obtains an ActivityManagerProxy proxy object of AcitivtyManagerService, and then initiates startActivity by the proxy object to communicate with AcitivtyManagerService through the Binder
4. ActivityManagerNative onTransact
The method is as follows:
@ Override public boolean onTransact (int code, Parcel data, Parcel reply, int flags) throws RemoteException {switch (code) {case START_ACTIVITY_TRANSACTION: {data. enforceInterface (IActivityManager. descriptor); IBinder B = data. readStrongBinder (); IApplicationThread app = ApplicationThreadNative. asInterface (B); String callingPackage = data. readString (); Intent intent = Intent. CREATOR. createFromPar Cel (data); String resolvedType = data. readString (); IBinder resultasks = data. readStrongBinder (); String resultWho = data. readString (); int requestCode = data. readInt (); int startFlags = data. readInt (); ProfilerInfo profilerInfo = data. readInt ()! = 0? ProfilerInfo. CREATOR. createFromParcel (data): null; Bundle options = data. readInt ()! = 0? Bundle. CREATOR. createFromParcel (data): null; int result = startActivity (app, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, options); reply. writeNoException (); reply. writeInt (result); return true ;... omitted part of the code ...}}}
Let's first look at this sentence, get the proxy object of ApplicationThreadNative, and then call the startActivity method. This method is implemented in ActivityManagerService. That's right. Here we also use Binder communication,
IApplicationThread app = ApplicationThreadNative.asInterface(b);int result = startActivity(app, callingPackage, intent, resolvedType,
Let's take a look at the inheritance relationship of ApplicationThreadNative:
5. startActivity in ActivityManagerService
@Override 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()); } @Override 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, null); }
The startActivityMayWait method in ActivityStarter is called in the startActivityAsUser method:
Final int Invocation (IApplicationThread caller, Intent intent, Intent identifier, String identifier, ActivityInfo aInfo, ResolveInfo rInfo, callback voiceSession, response timeout, IBinder resul.pdf, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, Activity Options options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord [] outActivity, ActivityStackSupervisor. activityContainer container, TaskRecord inTask ){... omitting some code... // convert the proxy object of ApplicationThread to callerAppcallerApp = mService. getRecordForAppLocked (caller );... omitting some code... // store callerApp and other information into ActivityRecordActivityRecord r = new ActivityRecord (mService, callerApp, callingUid, calling Package, intent, resolvedType, aInfo, mService. mConfiguration, resultRecord, resultWho, requestCode, componentSpecified, voiceSession! = Null, mSupervisor, container, options, sourceRecord );... omitting some code... err = startActivityUnchecked (r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask );}
6. The time sequence diagram is used to describe the subsequent steps.
In the realStartActivityLocked method, obtain the proxy object of ApplicationThreadProxy and call the scheduleLaunchActivity method to initiate inter-process communication. The Binder mechanism is used to communicate with the process where the application is located.
7. ApplicationThread
In ActivityThread, the internal class ApplicationThread inherits ApplicationThreadNative and communicates with the ApplicationThreadProxy proxy object of the realStartActivityLocked method.
8. Summary
After a large circle, I finally returned to ActivityThread.
Start Process:
1. Click the desktop App icon. The Launcher process uses the Binder IPC to initiate a startActivity request to the system_server process;
2. After the system_server process receives the request, it sends the request for creating the process to the zygote process;
3. the Zygote process fork is a new sub-process, that is, the App process;
4. The App process initiates the attachApplication request to the sytem_server process through the Binder IPC;
5. After receiving the request, the system_server process carries out a series of preparations and then sends the scheduleLaunchActivity request to the App process through the binder IPC;
6. The App process's binder thread (ApplicationThread) sends the LAUNCH_ACTIVITY message to the main thread through handler after receiving the request;
7. After receiving the Message, the main thread creates the target Activity through the launch mechanism and calls back Activity. onCreate () and other methods.
At this point, the App is officially started and enters the Activity lifecycle. After the onCreate/onStart/onResume method is executed, the main interface of the App is displayed after the UI rendering is complete.