In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-09 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains "how to use AMS". The content in the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn how to use AMS.
Start of the service
As mentioned earlier in the SystemServer chapter, the services of the system are generally started through the SystemServer process, and AMS is no exception.
/ / SystemServer.java private void startBootstrapServices () {/ /... / / Activity manager runs the show. TraceBeginAndSlog ("StartActivityManager"); mActivityManagerService = mSystemServiceManager.startService (ActivityManagerService.Lifecycle.class). GetService (); mActivityManagerService.setSystemServiceManager (mSystemServiceManager); mActivityManagerService.setInstaller (installer); traceEnd ();} / / reflection is used in the middle, as mentioned earlier. Public void startService (@ NonNull final SystemService service) {/ / Register it. MServices.add (service); / / Start it. Long time = SystemClock.elapsedRealtime (); try {service.onStart ();} catch (RuntimeException ex) {throw new RuntimeException ("Failed to start service" + service.getClass (). GetName () + ": onStart threw an exception", ex);}} / / ActivityManagerService.java public static final class Lifecycle extends SystemService {private final ActivityManagerService mService Public Lifecycle (Context context) {super (context); mService = new ActivityManagerService (context);} @ Override public void onStart () {mService.start ();} @ Override public void onBootPhase (int phase) {mService.mBootPhase = phase If (phase = = PHASE_SYSTEM_SERVICES_READY) {mService.mBatteryStatsService.systemServicesReady (); mService.mServices.systemServicesReady ();}} @ Override public void onCleanupUser (int userId) {mService.mBatteryStatsService.onCleanupUser (userId);} public ActivityManagerService getService () {return mService }}
You can see that by calling the onStart method in the inner class ActivityManagerService.Lifecycle, AMS is started and the start method of AMS is called.
Let's take a brief look at the instantiation method and start method of AMS:
Public ActivityManagerService (Context systemContext) {mContext = systemContext; mFactoryTest = FactoryTest.getMode (); mSystemThread = ActivityThread.currentActivityThread (); mUiContext = mSystemThread.getSystemUiContext (); mHandlerThread = new ServiceThread (TAG, THREAD_PRIORITY_FOREGROUND, false / * allowIo*/); mHandlerThread.start (); mHandler = new MainHandler (mHandlerThread.getLooper ()); mUiHandler = mInjector.getUiHandler (this) / /... MServices = new ActiveServices (this); mProviderMap = new ProviderMap (this); mAppErrors = new AppErrors (mUiContext, this); / / TODO: Move creation of battery stats service outside of activity manager service. MBatteryStatsService = new BatteryStatsService (systemContext, systemDir, mHandler); mBatteryStatsService.getActiveStatistics (). ReadLocked (); mBatteryStatsService.scheduleWriteToDisk (); mOnBattery = DEBUG_POWER? True: mBatteryStatsService.getActiveStatistics (). GetIsOnBattery (); mBatteryStatsService.getActiveStatistics (). SetCallback (this); mStackSupervisor = createStackSupervisor (); mStackSupervisor.onConfigurationChanged (mTempConfig); mActivityStartController = new ActivityStartController (this); mRecentTasks = createRecentTasks (); mStackSupervisor.setRecentTasks (mRecentTasks); mLockTaskController = new LockTaskController (mContext, mStackSupervisor, mHandler); mLifecycleManager = new ClientLifecycleManager () MProcessCpuThread = new Thread ("CpuTracker") / /...} private void start () {removeAllProcessGroups (); mProcessCpuThread.start (); mBatteryStatsService.publish (); mAppOpsService.publish (mContext); Slog.d ("AppOps", "AppOpsService published"); LocalServices.addService (ActivityManagerInternal.class, new LocalService ()) / / Wait for the synchronized block started in mProcessCpuThread, / / so that any other acccess to mProcessCpuTracker from main thread / / will be blocked during mProcessCpuTracker initialization. Try {mProcessCpuInitLatch.await ();} catch (InterruptedException e) {Slog.wtf (TAG, "Interrupted wait during start", e); Thread.currentThread (). Interrupt (); throw new IllegalStateException ("Interrupted wait during start");}
The code is very long, and I only intercepted part of it.
In the constructor, some objects are mainly initialized, such as Context, ActivityThrad, Handler, CPU monitoring thread, and some ActivityStackSupervisor, ActivityStarter and other objects that will be used later.
In the start method, the main thing is to start the CPU monitoring thread, and then register the battery status service and rights management service.
Initial work
After AMS is started, we will secretly do some work when SystemServer starts the three major services. We can see by searching the mActivityManagerService variable:
Private void startBootstrapServices () {/ / 1, initialize the power manager mActivityManagerService.initPowerManagement (); / / 2, set up the application instance for the system process and start it. MActivityManagerService.setSystemProcess ();} private void startCoreServices () {/ / launch UsageStatsManager to query the usage of the application mSystemServiceManager.startService (UsageStatsService.class); mActivityManagerService.setUsageStatsManager (LocalServices.getService (UsageStatsManagerInternal.class)); traceEnd ();} private void startOtherServices () {/ / install the Providers mActivityManagerService.installSystemProviders () of the system / / start WMS and set the WMS relationship for AMS wm = WindowManagerService.main (context, inputManager, mFactoryTestMode! = FactoryTest.FACTORY_TEST_LOW_LEVEL,! mFirstBoot, mOnlyCore, new PhoneWindowManager ()); mActivityManagerService.setWindowManager (wm) / /...} public void setSystemProcess () {try {ServiceManager.addService (Context.ACTIVITY_SERVICE, this, / * allowIsolated= * / true, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);}
In the second step, the setSystemProcess method registers the AMS into the ServiceManager, so that if you need to use AMS, you can obtain it through ServiceManager, which we will talk about in a minute.
Start to say so much, are relatively boring content, so there is no in-depth, have an impression on the line, if you need to use the relevant knowledge, you will know where to find it.
Viewing the working content of AMS from the start-up process
In order to understand the specific work of AMS, let's start from the startup process of Activity.
As mentioned in the app startup process above, the startActivityForResult method goes to the mInstrumentation.execStartActivity method:
/ / mInstrumentation.execStartActivity int result = ActivityManager.getService () .startActivity (whoThread, who.getBasePackageName (), intent, intent.resolveTypeIfNeeded (who.getContentResolver ()), token, target! = null? Target.mEmbeddedID: null, requestCode, 0, null, options); checkStartActivityResult (result, intent); public static IActivityManager getService () {return IActivityManagerSingleton.get () } private static final Singleton IActivityManagerSingleton = new Singleton () {@ Override protected IActivityManager create () {final IBinder b = ServiceManager.getService (Context.ACTIVITY_SERVICE); final IActivityManager am = IActivityManager.Stub.asInterface (b); return am;}}
You can see that the ServiceManager.getService (Context.ACTIVITY_SERVICE) here is a little familiar with finally getting the IBinder type reference of AMS. Yes, it just called the setSystemProcess method specifically to register the AMS in the ServiceManager. Then when we want to use the method of the relevant service, we get the reference to the corresponding service through Servermanager.
Here is to get the IActivityManager object, IActivityManager is actually the proxy of AMS in the current process, the logic here is to do a communication between processes through AIDL. Because these services, including the AMS we are talking about today, are in the SystemServer process, and what we actually use is in our own application process, it involves inter-process communication. Here we use the Binder mechanism for communication.
Binder,ServiceManager, which is a complete process of Binder communication, not only AMS, but also other services such as WMS basically communicate between processes through Binder mechanism. You can look forward to the Binder chapter mentioned later.
Looking at the startup process, we call the startActivity method of AMS through Binder, and then call the startActivity method of ActivityStarter, in which we find a new class:
/ / ActivityStarter.java private int startActivity (...) {ActivityRecord r = new ActivityRecord (mService, callerApp, callingPid, callingUid, callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration (), resultRecord, resultWho, requestCode, componentSpecified, voiceSession! = null, mSupervisor, checkedOptions, sourceRecord); if (outActivity! = null) {outActivity [0] = r;} / /. Return startActivity (r, sourceRecord, voiceSession, voiceInteractor, startFlags, true / * doResume * /, checkedOptions, inTask, outActivity);}
ActivityRecord
This class translates to a record of Activity, so the guess is related to Activity. Let's click into it to see what it contains:
Final ActivityManagerService service; / / owner final IApplicationToken.Stub appToken; / / window manager token final ActivityInfo info; / / all about me ApplicationInfo appInfo; / / information about activity's app final int userId; / / Which user is this running for? Final String packageName; / / the package implementing intent's component final String processName; / / process where this component wants to run final String taskAffinity; / / as per ActivityInfo.taskAffinity private int icon; / / resource identifier of activity's icon. Private int logo; / / resource identifier of activity's logo. Private int theme; / / resource identifier of activity's theme. Int launchMode; / / the launch mode activity attribute.
I have retained some of the more commonly used attributes, and everyone should be able to see what it is, such as the current Activity theme-theme, the current Activity token--apptoken, and the current Activity package name-packageName.
So this ActivityRecord actually keeps and records all the information of the Activity.
Then take a look at the process, and then resume the execution to the startActivityUnchecked method, in which we can see a new class-- TaskRecord.
TaskRecord
Private int startActivityUnchecked (final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord [] outActivity) {if (mStartActivity.resultTo = = null & & mInTask = = null & &! mAddingToTask & & (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK)! = 0) {newTask = true; 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 ();}} / / create a new task stack private void setTaskToCurrentTopOrCreateNewTask () {/ /. Final ActivityRecord prev = mTargetStack.getTopActivity (); final TaskRecord task = (prev! = null)? Prev.getTask (): mTargetStack.createTaskRecord (mSupervisor.getNextTaskIdForUserLocked (mStartActivity.userId), mStartActivity.info, mIntent, null, null, true, mStartActivity, mSourceRecord, mOptions); addOrReparentStartingActivity (task, "setTaskToCurrentTopOrCreateNewTask"); mTargetStack.positionChildWindowContainerAtTop (task) } / / add Ac to private void addOrReparentStartingActivity (TaskRecord parent, String reason) {if (mStartActivity.getTask () = = null | | mStartActivity.getTask () = = parent) {parent.addActivityToTop (mStartActivity);} else {mStartActivity.reparent (parent, parent.mActivities.size () / * top * /, reason);}}
As you can see from the code, when the Activity we launch requires a new task stack (for example, the startup mode is FLAG_ACTIVITY_NEW_TASK), we go to the setTaskToCurrentTopOrCreateNewTask method, create a new TaskRecord class, and add the current Activity to the top of the stack through the addActivityToTop method.
So this TaskRecord class is a task stack class, and its function is to maintain all the Activity in the stack and go in to see what variables the class has:
Final int taskId; / / Unique identifier for this task. / * * List of all activities in the task arranged in history order * / final ArrayList mActivities; / * * Current stack. Setter must always be used to update the value. * / private ActivityStack mStack
Here are some interceptions, and you can find that there is a task id--taskId, all the ActivityRecord--mActivities of the task stack, and I don't know what this is, but I know that it is used to manage all the Activity and task stack butler-ActivityStack.
ActivityStack
If you start the process and go further, you will come to the resumeFocusedStackTopActivityLocked method of ActivityStackSupervisor:
/ / ActivityStackSupervisor.java / * * The stack containing the launcher app. Assumed to always be attached to * Display.DEFAULT_DISPLAY. * / ActivityStack mHomeStack; / * * The stack currently receiving input or launching the next activity. * / ActivityStack mFocusedStack; / * * If this is the same as mFocusedStack then the activity on the top of the focused stack has * been resumed. If stacks are changing position this will hold the old stack until the new * stack becomes resumed after which it will be set to mFocusedStack. * / private ActivityStack mLastFocusedStack; public ActivityStackSupervisor (ActivityManagerService service, Looper looper) {mService = service; mLooper = looper; mHandler = new ActivityStackSupervisorHandler (looper);} boolean resumeFocusedStackTopActivityLocked (ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {if (targetStack! = null & & isFocusedStack (targetStack)) {return targetStack.resumeTopActivityUncheckedLocked (target, targetOptions) } final ActivityRecord r = mFocusedStack.topRunningActivityLocked (); if (r = = null | |! r.isState (RESUMED)) {mFocusedStack.resumeTopActivityUncheckedLocked (null, null);} else if (r.isState (RESUMED)) {/ / Kick off any lingering app transitions form the MoveTaskToFront operation. MFocusedStack.executeAppTransition (targetOptions);} return false;}
ActivityStackSupervisor is a class that manages ActivityStack, which is created in the constructor of AMS, and you can see that there are some task stacks in this class, such as mHomeStack-- that contains Launcher APP's Activity.
Then take a look at what good things are stored in the housekeeper ActivityStack's house:
Enum ActivityState {INITIALIZING, RESUMED, PAUSING, PAUSED, STOPPING, STOPPED, FINISHING, DESTROYING, DESTROYED} private final ArrayList mTaskHistory = new ArrayList (); final ArrayList mLRUActivities = new ArrayList (); ActivityRecord mPausingActivity = null; ActivityRecord mLastPausedActivity = null
As you can see, in ActivityStack:
There is an enumeration ActivityState that stores all the states of the Activity.
There are some lists of TaskRecord and ActivityRecord, such as the list of task stacks that mTaskHistory-- has not been destroyed, and the list header calculated by mLRUActivities-- through LRU is the least used ActivityRecord list of Activity recently.
There are also ActivityRecord corresponding to Activity in some special states, such as the Activity being paused and the last paused Activity.
Finally, the startup process goes to the startProcessLocked method of AMS, and then communicates with the Zygote process, the fork process. Let's not talk about it later.
Thank you for your reading, the above is the content of "how to use AMS", after the study of this article, I believe you have a deeper understanding of how to use AMS, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
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.