In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly introduces the relevant knowledge of "what is the startup process of Activity in Android". The editor shows you the operation process through an actual case. The operation method is simple, fast and practical. I hope this article "what is the startup process of Activity in Android" can help you solve the problem.
Analyze the startup process of Android Activity
As one of the four major components of Android, Activity is also the most basic component, which is responsible for all the functions of interacting with users. The startup process of Activity is not a mysterious thing, so let's simply analyze the startup process of Activity from the perspective of source code.
The root Activity generally refers to the MainActivity in our project, which represents an android application and is generally launched in a new process. In the Android system, all the Activity components are stored on the stack, and we launch a new Activity component on top of the previous Activity. So what is the process of opening an App from the desktop (Launcher), as follows:
(1) Launcher sends a request to ActivityManagerService to start MainActivity
(2) ActivityManagerService first saves the relevant information about MainActivity, and then sends a request to Launcher to make it abort.
(3) after receiving the aborted state, Launcher will send a request to ActivityManagerService that it has entered the aborted state, so that ActivityManagerService can continue to perform the operation of starting MainActivity.
(4) ActivityManagerService checks the process used to run MainActivity, and if it does not exist, start a new process
(5) after the new application process is started, a request for startup completion will be sent to ActivityManagerService, so that ActivityManagerService can continue to start MainActivity.
(6) ActivityManagerService sends the MainActivity-related information saved in step (2) to the newly created process to facilitate the process to start the MainActivity component.
Launcher.startActivitySafely
Boolean startActivitySafely (Intent intent, Object tag) {intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK); try {startActivity (intent); return true;} catch (ActivityNotFoundException e) {}}
When we click the application icon on Launcher, the startActivitySafely method is called. The Activity information that needs to be started is stored in intent, including action, category, and so on. So how does Launcher get this information in intent? First, the system starts a management service called PackageManagerService and installs the application through it. In the process, PackageManagerService parses the configuration file AndroidManifest.xml of the application to get the component information in the program (including Activity, Service, Broadcast, etc.). Then PackageManagerService queries all Activity whose action is "android.intent.action.MAIN" and category is "android.intent.category.LAUNCHER" Then create a shortcut icon for each application and associate the program information with it. In the above code, the startup flag bit of Activity is set to "Intent.FLAG_ACTIVITY_NEW_TASK" so that he can start in a new task.
Activity.startActivity
@ Override public void startActivity (Intent intent, @ Nullable Bundle options) {if (options! = null) {startActivityForResult (intent,-1, options);} else {startActivityForResult (intent,-1);}}
Call startActivityForResult, and the second parameter (requestCode) of-1 means that there is no need to pass back the result when Activity is closed.
Activity.startActivityForResult
Public void startActivityForResult (Intent intent, int requestCode, @ Nullable Bundle options) {if (mParent = = null) {/ / General Activity whose mParent is null Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity (this, mMainThread.getApplicationThread (), mToken, this,intent, requestCode, options); if (ar! = null) {/ / send the result, that is, onActivityResult will be called mMainThread.sendActivityResult (mToken, mEmbeddedID, requestCode, ar.getResultCode (), ar.getResultData ()) } if (requestCode > = 0) {mStartedActivity = true;} final View decor = mWindow! = null? MWindow.peekDecorView (): null; if (decor! = null) {decor.cancelPendingInputEvents ();}} else {/ / Activity within ActivityGroup, internal processing logic is similar to if (options! = null) {mParent.startActivityFromChild (this, intent, requestCode, options);} else {mParent.startActivityFromChild (this, intent, requestCode) }} if (options! = null & &! isTopOfTask ()) {mActivityTransitionState.startExitOutTransition (this, options);}}
It is not difficult to find that in the end, mInstrumentation.execStartActivity is actually called to start the Activity,mInstrumentation type Instrumentation, which is used to monitor the interaction between the program and the system. MInstrumentation performs the startup operation of Activity on his behalf, so that he can monitor the interaction.
The type of mMainThread is ActivityThread, which is used to describe an application process. Each program started by the system will load an instance of ActivityThread in it and save the instance in the member variable mMainThread of Activity, while mMainThread.getApplicationThread () is used to get a local Binder object of type ApplicationThread. MToken, which is of type IBinder, is a proxy object for Binder and only thinks of a local Binder object of type ActivityRecord in ActivityManagerService. Each Activity that has been started has a corresponding ActivityRecord object in ActivityManagerService, which is used to maintain the running status and information of Activity.
Instrumentation.execStartActivity
Public ActivityResult execStartActivity (Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {IApplicationThread whoThread = (IApplicationThread) contextThread; if (mActivityMonitors! = null) {synchronized (mSync) {final int N = mActivityMonitors.size (); for (int iTuno; iTun0? Am.getResult (): null;} break;} try {intent.migrateExtraStreamToClipData (); intent.prepareToLeaveProcess (); int result = ActivityManagerNative.getDefault (). StartActivity (whoThread, who.getBasePackageName (), intent, intent.resolveTypeIfNeeded (who.getContentResolver ()), token, target! = null? Target.mEmbeddedID: null, requestCode, 0, null, options); / / this is where the activity is really opened, and its core functions are completed in whoThread. CheckStartActivityResult (result, intent); / / handle various exceptions, such as ActivityNotFound} catch (RemoteException e) {} return null;}
The above code shows that you get a proxy object for ActivityManagerService through ActivityManagerNative.getDefault (), and then call his startActivity method to tell ActivityManagerService to start Activity.
There are also a series of processes, follow the source code, it is not difficult to find, and finally, is to call ApplicationThread's scheduleLaunchActivity to start Activity.
Application.scheduleLaunchActivity
Public final void scheduleLaunchActivity (Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List pendingResults, List pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {updateProcessState (procState, false); ActivityClientRecord r = new ActivityClientRecord (); r.token = token; r.ident = ident; r.intent = intent; r.referrer = referrer; r.voiceInteractor = voiceInteractor; r.activityInfo = info R.compatInfo = compatInfo; r.state = state; r.persistentState = persistentState; r.pendingResults = pendingResults; r.pendingIntents = pendingNewIntents; r.startsNotResumed = notResumed; r.isForward = isForward; r.profilerInfo = profilerInfo; updatePendingConfiguration (curConfig); sendMessage (H.LAUNCH_ACTIVITY, r);}
The main thing the above code does is construct an ActivityClientRecord and then call sendMessage to send a message. In the corresponding process of the application, each Activity component is described by an ActivityClientRecord object, which is stored in the member variable mActivities of the ActivityThread class. So how does Handler handle this message?
H.handleMessage
Switch (msg.what) {/ / message type 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); / / processing message Trace.traceEnd (Trace.TRACE_TAG_ACTIVITY_MANAGER);} break Case RELAUNCH_ACTIVITY: {Trace.traceBegin (Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); ActivityClientRecord r = (ActivityClientRecord) msg.obj; handleRelaunchActivity (r); Trace.traceEnd (Trace.TRACE_TAG_ACTIVITY_MANAGER);} break; case PAUSE_ACTIVITY: Trace.traceBegin (Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause") HandlePauseActivity ((IBinder) msg.obj, false, (msg.arg1&1)! = 0, msg.arg2, (msg.arg1&2)! = 0); maybeSnapshot (); Trace.traceEnd (Trace.TRACE_TAG_ACTIVITY_MANAGER); break;.}
First convert the obj in msg to an ActivityClientRecord object, and then call to get a LoaderApk object and save it in the member variable packageInfo of the ActivityClientRecord object. The Loader object is used to describe a loaded APK file. Finally, call handleLaunchActivity to start the Activity component.
ActivityThread.handleLaunchActivity
Private void handleLaunchActivity (ActivityClientRecord r, Intent customIntent) {unscheduleGcIdler (); mSomeActivitiesChanged = true; if (r.profilerInfo! = null) {mProfiler.setProfiler (r.profilerInfo); mProfiler.startProfiling ();} handleConfigurationChanged (null, null); if (localLOGV) Slog.v (TAG, "Handling launch of" + r); WindowManagerGlobal.initialize (); Activity a = performLaunchActivity (r, customIntent) / / performLaunchActivity actually completes the activity call, Activity is instantiated, onCreate is called if (a! = null) {r.createdConfig = new Configuration (mConfiguration); Bundle oldState = r.state.handleResumeActivity (r.token, false, r.isForward, / / then call the Resume of the Activity instance (the user interface is visible)! r.activity.mFinished & &! r.startsNotResumed) If (! r.activity.mFinished & & r.startsNotResumed) {try {r.activity.mCalled = false; mInstrumentation.callActivityOnPause (r.activity); / / finish first tune onPause if (r.isPreHoneycomb ()) {r.state = oldState } if (! r.activity.mCalled) {throw new SuperNotCalledException ("Activity" + r.intent.getComponent (). ToShortString () + "did not call through to super.onPause ()");}} catch (SuperNotCalledException e) {throw e } catch (Exception e) {if (! mInstrumentation.onException (r.activity, e)) {throw new RuntimeException ("Unable to pause activity" + r.intent.getComponent () .toShortString () + ":" + e.toString (), e);}} r.paused = true }} else {try {ActivityManagerNative.getDefault () / / finishActivity same principle. FinishActivity (r.token, Activity.RESULT_CANCELED, null, false);} catch (RemoteException ex) {}
At this point, it will be very clear. After taking a breath, did you suddenly relax? let's take a look at what performLaunchActivity does. ~ the performLaunchActivity function loads the derived class of the user-defined Activity and executes its onCreate function, which will return this Activity object.
ActivityThread.performLaunchActivity
Private Activity performLaunchActivity (ActivityClientRecord r, Intent customIntent) {ActivityInfo aInfo = r.activityInfo; if (r.packageInfo = = null) {r.packageInfo = getPackageInfo (aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE);} / / extract the startup parameters (package name, class name, etc.) of the target activity from intent 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);} Activity activity = null; try {java.lang.ClassLoader cl = r.packageInfo.getClassLoader (); / / load Activity class files into memory activity = mInstrumentation.newActivity (/ / create Activity instance 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) }} try {Application app = r.packageInfo.makeApplication (false, mInstrumentation); if (localLOGV) Slog.v (TAG, "Performing launch of" + r) If (localLOGV) Slog.v (TAG, r + ": app=" + app + ", appName=" + app.getPackageName () + ", pkg=" + r.packageInfo.getPackageName () + ", comp=" + r.intent.getComponent (). ToShortString () + ", dir=" + r.packageInfo.getAppDir ()); if (activity! = null) {Context appContext = createBaseContextForActivity (r, activity) / initialize the Context object as the context of Activity CharSequence title = r.activityInfo.loadLabel (appContext.getPackageManager ()); Configuration config = new Configuration (mCompatConfiguration); if (DEBUG_CONFIGURATION) Slog.v (TAG, "Launching activity" + r.activityInfo.name + "with config" + config) 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); if (customIntent! = null) {activity.mIntent = customIntent;} r.lastNonConfigurationInstances = null; activity.mStartedActivity = false; int theme = r.activityInfo.getThemeResource () If (theme! = 0) {activity.setTheme (theme);} activity.mCalled = false; if (r.isPersistable ()) {/ / the following is the onCreate method called to acitivity: mInstrumentation.callActivityOnCreate (activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate (activity, r.state) } / / at this point, the Activity startup process is over, and its life cycle is managed by ApplicationThread if (! activity.mCalled) {throw new SuperNotCalledException ("Activity" + r.intent.getComponent (). ToShortString () + "did not call through to super.onCreate ()");} r.activity = activity; r.stopped = true; if (! r.activity.mFinished) {activity.performStart () R.stopped = false;} if (! r.activity.mFinished) {if (r.isPersistable ()) {if (r.state! = null | | r.persistentState! = null) {mInstrumentation.callActivityOnRestoreInstanceState (activity, r.state, r.persistentState);} else if (r.state! = null) {mInstrumentation.callActivityOnRestoreInstanceState (activity, r.state) }} if (! r.activity.mFinished) {activity.mCalled = false; if (r.isPersistable ()) {mInstrumentation.callActivityOnPostCreate (activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnPostCreate (activity, r.state) } if (! activity.mCalled) {throw new SuperNotCalledException ("Activity" + r.intent.getComponent (). ToShortString () + "did not call through to super.onPostCreate ()");}} r.paused = true; mActivities.put (r.token, r); / / Save the ActivityRecord object in ActivityThread's mActivities} catch (SuperNotCalledException e) {throw e } catch (Exception e) {if (! mInstrumentation.onException (activity, e)) {throw new RuntimeException ("Unable to start activity" + component + ":" + e.toString (), e);}} return activity;}
Token in ActivityRecord is a proxy object for Binder. Like the ActivityClientRecord object, it is used to describe the Activity component that is started, except that the former is used in ActivityManagerService and the latter is used in the application process.
At this point, the startup process of Activity is analyzed. In fact, the startup process of MainActivity can also be regarded as the startup process of the application.
The startup process of the sub-Activity is similar to that of the root Activity, as follows:
(1) MainActivity sends a request for automatic ChildActivity to ActivityManagerService
(2) ActivityManagerService first saves the information of ChildActivity, and then sends a request for termination to MainActivity.
(3) when MainActivity receives a request to enter the aborted state, tell ActivityManagerService so that ActivityManagerService can continue to perform the operation of starting ChildActivity.
(4) ActivityManagerService checks whether the process run by ChildActivity exists, and sends ChildActivity information to him to start.
This is the end of the content about "what is the startup process of Activity in Android". Thank you for reading. If you want to know more about the industry, you can follow the industry information channel. The editor will update different knowledge points for you every day.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.