溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用AMS

發(fā)布時間:2021-10-20 14:33:12 來源:億速云 閱讀:156 作者:iii 欄目:移動開發(fā)

這篇文章主要講解了“如何使用AMS”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“如何使用AMS”吧!

服務的啟動

之前在SystemServer章節(jié)說過,系統(tǒng)的服務一般都是通過SystemServer進程啟動的,AMS也不例外。

//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();     }      //中間用到了反射,之前說過。       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;         }     }

可以看到,通過調(diào)用了ActivityManagerService.Lifecycle這個內(nèi)部類中的onStart方法,啟動了AMS,并調(diào)用了AMS的start方法。

再簡單看看AMS的實例化方法和start方法:

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

代碼很長,我只截取了一部分。

在構造函數(shù)中,主要初始化了一些對象,比如Context、ActivityThrad、Handler、CPU監(jiān)控線程,還有一些后文要用到的ActivityStackSupervisor、ActivityStarter等對象,

在start方法中,主要就是啟動了CPU監(jiān)控線程,然后注冊了電池狀態(tài)服務和權限管理服務。

初始工作

AMS被啟動之后,還會在SystemServer啟動三大服務的時候偷偷干一些工作,我們搜索下mActivityManagerService變量就可以看到:

private void startBootstrapServices() {    //1、初始化電源管理器       mActivityManagerService.initPowerManagement();       //2、為系統(tǒng)進程設置應用程序?qū)嵗印?nbsp;      mActivityManagerService.setSystemProcess();   }    private void startCoreServices() {       // 啟動UsageStatsManager,用于查詢應用的使用情況       mSystemServiceManager.startService(UsageStatsService.class);       mActivityManagerService.setUsageStatsManager(               LocalServices.getService(UsageStatsManagerInternal.class));       traceEnd();   }    private void startOtherServices() {     //安裝系統(tǒng)的Providers       mActivityManagerService.installSystemProviders();        //啟動WMS,并為AMS設置WMS關系       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);       }   }

其中第二步setSystemProcess方法中,會注冊AMS到ServiceManager中,這樣后續(xù)如果需要用到AMS的時候就可以通過ServiceManager進行獲取,下面馬上就要講到。

啟動就說這么多,都是比較枯燥的內(nèi)容,所以也沒有深入下去,有個印象就行,以后如果需要用到相關知識就知道去哪里找了。

從啟動流程看AMS工作內(nèi)容

為了了解AMS的具體工作,我們就從Activity的啟動過程看起。

上文app啟動流程中說過,startActivityForResult方法會轉到mInstrumentation.execStartActivity方法:

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

可以看到,最終要拿到AMS的IBinder類型引用,這里的ServiceManager.getService(Context.ACTIVITY_SERVICE)是不是有點熟悉,沒錯,就是剛才專門調(diào)用了setSystemProcess方法對AMS進行了注冊在ServiceManager中。然后我們要使用相關服務的方法的時候,就通過Servermanager拿到對應服務的引用。

這里也就是拿到了IActivityManager對象,IActivityManager其實就是AMS在當前進程的代理,這里的邏輯就是通過AIDL做了一個進程間的通信。因為這些服務,包括我們今天說的AMS都是在SystemServer進程中的,而我們實際用到的時候是在我們自己的應用進程中,所以就涉及到進程間通信了,這里是用的Binder機制進行通信。

Binder,ServiceManager,這是Binder通信一整套流程,不光是AMS,包括其他的WMS等服務基本上都是通過Binder機制進行進程間通信的,具體內(nèi)容可以期待下后面說到的Binder章節(jié)。

接著看啟動流程,通過Binder調(diào)用到了AMS的startActivity方法,然后會調(diào)用到ActivityStarter的startActivity方法,在這個方法中,我們發(fā)現(xiàn)一個新的類:

//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

這個類翻譯過來是Activity的記錄,所以猜測是和Activity有關,我們點進去看看它里面包含了什么:

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.

我保留了一些比較常用的屬性,大家應該都看得出來是什么了吧,比如當前Activity的主題&mdash;&mdash;theme,當前Activity的token&mdash;&mdash;apptoken,當前Activity的包名&mdash;&mdash;packageName。

所以這個ActivityRecord其實就是保存記錄了Activity的所有信息。

接著看流程,后續(xù)會執(zhí)行到startActivityUnchecked方法,這個方法中,我們又可以看到一個新的類&mdash;&mdash;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();         }  }  // 新建一個任務棧     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);     }      //添加Ac到棧頂     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);         }     }

從代碼中可知,當我們啟動的Activity需要一個新的任務棧的時候(比如啟動模式為FLAG_ACTIVITY_NEW_TASK),我們會走到setTaskToCurrentTopOrCreateNewTask方法中,新建一個TaskRecord類,并且把當前的Activity通過addActivityToTop方法添加到棧頂。

所以這個TaskRecord類就是一個任務棧類了,它的作用就是維護棧內(nèi)的所有Activity,進去看看這個類有哪些變量:

final int taskId;       // Unique identifier for this task.     /** List of all activities in the task arranged in history order */    final ArrayList<ActivityRecord> mActivities;     /** Current stack. Setter must always be used to update the value. */    private ActivityStack mStack;

這里截取了一些,可以發(fā)現(xiàn)有任務id&mdash;&mdash;taskId,任務棧的所有ActivityRecord&mdash;&mdash;mActivities,以及這個還不知道是什么的但是我知道是用來管理所有Activity和任務棧的大管家&mdash;&mdash;ActivityStack。

ActivityStack

啟動流程再往后面走,就會走到的ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法:

//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是一個管理ActivityStack的類,在AMS的構造方法中被創(chuàng)建,這個類中可以看到有一些任務棧,比如mHomeStack&mdash;&mdash;包含了Launcher  APP的Activity。

然后再看看ActivityStack這個大管家家里存儲了什么好東西:

enum ActivityState {      INITIALIZING,      RESUMED,      PAUSING,      PAUSED,      STOPPING,      STOPPED,      FINISHING,      DESTROYING,      DESTROYED  }     private final ArrayList<TaskRecord> mTaskHistory = new ArrayList<>();   final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>();   ActivityRecord mPausingActivity = null;   ActivityRecord mLastPausedActivity = null;

可以看到,在ActivityStack中:

  • 有一個枚舉ActivityState,存儲了Activity的所有狀態(tài)。

  • 有一些TaskRecord和ActivityRecord的列表,比如mTaskHistory&mdash;&mdash;沒有被銷毀的任務棧列表,mLRUActivities&mdash;&mdash;通過LRU計算的列表頭目是最近最少使用的Activity的ActivityRecord列表。

  • 還有一些特殊狀態(tài)的Activity對應的ActivityRecord,比如正在暫停的Activity,上一個暫停過的Activity。

最后,啟動流程會走到AMS的startProcessLocked方法,然后跟Zygote進程通信,fork進程。后續(xù)就不說了。

感謝各位的閱讀,以上就是“如何使用AMS”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對如何使用AMS這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI