3 ActivityManagerService(一)App啟動流程

所有代碼都是Android 11

ActivityManagerService 簡稱 AMS ,那么他在系統(tǒng)調(diào)用過程中是干什么的,他到底管理了什么,他在系統(tǒng)調(diào)度又充當了什么角色,我們接下來就開始具體分析一下,由于ActivityManagerService 是一個非常功能非常復(fù)雜且代碼特別龐大的一個類,想要了解ActivityManagerService 就需要將他里面非常多的功能拆分來講解一下,本篇博客我會先將 ActivityManagerService 的啟動流程說一下,了解一下 ActivityManagerService 在啟動過程中都持有了哪些比較重要的對象,后續(xù)在針對不同的對象做具體的分析

ActivityManagerService 簡稱 AMS

ActivityManagerService.Lifecycle.class 代理 AMS ,并創(chuàng)建ams

我的關(guān)于 FrameWork 的第一篇和第三篇都有介紹 SystemServer 通過 SystemServiceMananger 啟動各個服務(wù)的流程,同時我在前面的博客里面也多次提到,AMS的啟動流程與其他 SystemService 有些不同,那就不是他不會通過代理類將自身添加到ServiceManager , 那么他是如何被添加到ServiceManager 當中的呢,

mActivityManagerService = ActivityManagerService.Lifecycle.startService(
              mSystemServiceManager, atm); // 啟動AMS

通過 ActivityManagerService.Lifecycle 這個代理類解決java 單一繼承的問題,來啟動 AMS , 并且將 AcivityTaskManagerService 作為參數(shù)傳入,AcivityTaskManagerService 是在android 10 版本中引入的一個功能,至于為什么要引入他,可能google 覺得 AMS 功能太復(fù)雜了,需要將部分功能繼續(xù)封裝一下吧

  public static final class Lifecycle extends SystemService {
      private final ActivityManagerService mService;
      private static ActivityTaskManagerService sAtm;

      public Lifecycle(Context context) {
          super(context);
          mService = new ActivityManagerService(context, sAtm);
      }

      public static ActivityManagerService startService(
              SystemServiceManager ssm, ActivityTaskManagerService atm) {
          sAtm = atm;
          return ssm.startService(ActivityManagerService.Lifecycle.class).getService();
      }

      @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();
          } else if (phase == PHASE_ACTIVITY_MANAGER_READY) {
              mService.startBroadcastObservers();
          } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
              mService.mPackageWatchdog.onPackagesReady();
          }
      }

      @Override
      public void onUserStopped(@NonNull TargetUser user) {
          mService.mBatteryStatsService.onCleanupUser(user.getUserIdentifier());
      }

      public ActivityManagerService getService() {
          return mService;
      }
  }

代理類創(chuàng)建 AMS ,并且將 ATMS 作為參數(shù)給到 AMS ,我在前面說過 ams 并不是通過代理類將自身添加到 ServiceManager 當中的,那么他是如何添加進去的,帶著這個疑問,接下來看一下他的構(gòu)造方法

AMS 初始化方法 及內(nèi)容分析

  public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
      LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
      看起來像網(wǎng)絡(luò)管理
      mInjector = new Injector(systemContext);

      系統(tǒng)上下文,是在SystemServer進程fork出來后通過createSystemContext()創(chuàng)建的,即與SystemServer進程是一樣的
      mContext = systemContext;
      mFactoryTest = FactoryTest.getMode();


      mSystemThread -->系統(tǒng)進程的主線程 sCurrentActivityThread,這里是systemMain()中創(chuàng)建的ActivityThread對象。即也與SystemServer一樣的。
      mSystemThread = ActivityThread.currentActivityThread();

      MUiContext-->是通過SystemContext 創(chuàng)建的一個ContextImpl,并且是綁定過 Resource ,package 信息  以及其他信息
      mUiContext = mSystemThread.getSystemUiContext();

      Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
      
      一個HandlerThread 具有l(wèi)ooper
      mHandlerThread = new ServiceThread(TAG,THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
      mHandlerThread.start();
      處理AMS消息的handle ,looper 沒使用SystemServer 的,使用的是上面創(chuàng)建的那個looper
      mHandler = new MainHandler(mHandlerThread.getLooper());
      UiHandler對應(yīng)于Android中的Ui線程 , 使用的是SystemServer 中的主線程中的looper
      mUiHandler = mInjector.getUiHandler(this);
      又一個HandlerThread 具有l(wèi)ooper
      mProcStartHandlerThread = new ServiceThread(TAG + ":procStart",THREAD_PRIORITY_FOREGROUND, false /* allowIo */);
      mProcStartHandlerThread.start();
      綁定了上面looper的Handler  
      mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper());

      廠商定制修改這里
      mConstants = new ActivityManagerConstants(mContext, this, mHandler);
      
      管理Uid 的
      final ActiveUids activeUids = new ActiveUids(this, true /* postChangesToAtm */);
      持有了  platformService
      mPlatformCompat = (PlatformCompat) ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
      字面意思就是獲取進程列表
      mProcessList = mInjector.getProcessList(this);
      mProcessList.init(this, activeUids, mPlatformCompat);
      啟動一個線程  while(true) 查看內(nèi)存情況, 也存在一個wait 機制,方法是waitForPressure  ,不知道這個機制是什么樣的,但是確保不回一直遍歷
      mLowMemDetector = new LowMemDetector(this);
      這里面又創(chuàng)建了一個handlerThread,用來處理消息,這個類是用來減少后臺內(nèi)存的
      mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids);

      // Broadcast policy parameters
      final BroadcastConstants foreConstants = new BroadcastConstants(
              Settings.Global.BROADCAST_FG_CONSTANTS);
      foreConstants.TIMEOUT = BROADCAST_FG_TIMEOUT;

      final BroadcastConstants backConstants = new BroadcastConstants(
              Settings.Global.BROADCAST_BG_CONSTANTS);
      backConstants.TIMEOUT = BROADCAST_BG_TIMEOUT;

      final BroadcastConstants offloadConstants = new BroadcastConstants(
              Settings.Global.BROADCAST_OFFLOAD_CONSTANTS);
      offloadConstants.TIMEOUT = BROADCAST_BG_TIMEOUT;
      // by default, no "slow" policy in this queue
      offloadConstants.SLOW_TIME = Integer.MAX_VALUE;

      mEnableOffloadQueue = SystemProperties.getBoolean(
              "persist.device_config.activity_manager_native_boot.offload_queue_enabled", false);

  創(chuàng)建幾種廣播相關(guān)對象,前臺廣播、后臺廣播、offload廣播隊列。
      mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
              "foreground", foreConstants, false);
      mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
              "background", backConstants, true);
      mOffloadBroadcastQueue = new BroadcastQueue(this, mHandler,
              "offload", offloadConstants, true);
      mBroadcastQueues[0] = mFgBroadcastQueue;
      mBroadcastQueues[1] = mBgBroadcastQueue;
      mBroadcastQueues[2] = mOffloadBroadcastQueue;

     創(chuàng)建ActiveServices對象,管理 ServiceRecord
      mServices = new ActiveServices(this);
       創(chuàng)建ProviderMap對象,管理ContentProviderRecord
      mProviderMap = new ProviderMap(this);
      mPackageWatchdog = PackageWatchdog.getInstance(mUiContext);
      mAppErrors = new AppErrors(mUiContext, this, mPackageWatchdog);

      final File systemDir = SystemServiceManager.ensureSystemDir();

      創(chuàng)建電池統(tǒng)計服務(wù),并輸出到制定目錄
      mBatteryStatsService = new BatteryStatsService(systemContext, systemDir,
              BackgroundThread.get().getHandler());
      mBatteryStatsService.getActiveStatistics().readLocked();
      mBatteryStatsService.scheduleWriteToDisk();
      mOnBattery = DEBUG_POWER ? true
              : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
      mBatteryStatsService.getActiveStatistics().setCallback(this);
      mOomAdjProfiler.batteryPowerChanged(mOnBattery);

     adb shell dumpsys procstats 查看應(yīng)用進程信息
      mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
      
      //appops是在現(xiàn)有權(quán)限機制上新增的一套權(quán)限管理機制,主要針對一些高危的非必須系統(tǒng)應(yīng)用的權(quán)限,比如在其他應(yīng)用上顯示懸浮窗。
      mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);

      mUgmInternal = LocalServices.getService(UriGrantsManagerInternal.class);

      mUserController = new UserController(this);

      mPendingIntentController = new PendingIntentController(
              mHandlerThread.getLooper(), mUserController, mConstants);

      if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
          mUseFifoUiScheduling = true;
      }

      mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
      //Intent防火墻,Google定義了一組規(guī)則,來過濾intent,如果觸發(fā)了,則intent會被系統(tǒng)丟棄,
      //且不會告知發(fā)送者
      mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);

      得到ActivityTaskManagerService的對象,調(diào)用ATM.initialize
      mActivityTaskManager = atm;
      mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController,
              DisplayThread.get().getLooper());
      mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);

      啟動一個線程專門跟進cpu當前狀態(tài)信息,ams對當前cpu狀態(tài)了如指掌,可以更加高效的安排其他工作
      mProcessCpuThread = new Thread("CpuTracker") {
          @Override
          public void run() {
              synchronized (mProcessCpuTracker) {
                  mProcessCpuInitLatch.countDown();
                  mProcessCpuTracker.init();
              }
              while (true) {
                  try {
                      try {
                          synchronized(this) {
                              final long now = SystemClock.uptimeMillis();
                              long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
                              long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
                              //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
                              //        + ", write delay=" + nextWriteDelay);
                              if (nextWriteDelay < nextCpuDelay) {
                                  nextCpuDelay = nextWriteDelay;
                              }
                              if (nextCpuDelay > 0) {
                                  mProcessCpuMutexFree.set(true);
                                  this.wait(nextCpuDelay);
                              }
                          }
                      } catch (InterruptedException e) {
                      }
                      updateCpuStatsNow();
                  } catch (Exception e) {
                      Slog.e(TAG, "Unexpected exception collecting process stats", e);
                  }
              }
          }
      };

      mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext);

      // 加入Watchdog的監(jiān)控,監(jiān)聽進程,這個類每分鐘調(diào)用一次監(jiān)視器,如果進程沒有任何返回就殺掉
      Watchdog.getInstance().addMonitor(this);
      Watchdog.getInstance().addThread(mHandler);

      // bind background threads to little cores
      // this is expected to fail inside of framework tests because apps can't touch cpusets directly
      // make sure we've already adjusted system_server's internal view of itself first
      保活這塊相關(guān)代碼
      updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
      try {
          Process.setThreadGroupAndCpuset(BackgroundThread.get().getThreadId(),
                  Process.THREAD_GROUP_SYSTEM);
          Process.setThreadGroupAndCpuset(
                  mOomAdjuster.mCachedAppOptimizer.mCachedAppOptimizerThread.getThreadId(),
                  Process.THREAD_GROUP_SYSTEM);
      } catch (Exception e) {
          Slog.w(TAG, "Setting background thread cpuset failed");
      }

      // ActivityManagerInternal類的實現(xiàn)類
      mInternal = new LocalService();
      mPendingStartActivityUids = new PendingStartActivityUids(mContext);
  }

翻閱了很多資料,將所有能注釋的地方我都注釋了一下,其中非常有研究價值的是 關(guān)于?;?->updateOomAdjLocked 減少后臺內(nèi)存消耗-->OomAdjuster 與電池服務(wù)

在代理類的創(chuàng)建過程中會執(zhí)行他的start 方法

  private void start() {
      removeAllProcessGroups();
      開啟cpu監(jiān)控
      mProcessCpuThread.start();
      將電量服務(wù)添加到ServiceManager中
      mBatteryStatsService.publish();
      浮窗加強管理添加到ServiceManager中
      mAppOpsService.publish();
      Slog.d("AppOps", "AppOpsService published");
      LocalServices.addService(ActivityManagerInternal.class, mInternal);
      mActivityTaskManager.onActivityManagerInternalAdded();
      mPendingIntentController.onActivityManagerInternalAdded();
      // Wait for the synchronized block started in mProcessCpuThread,
      // so that any other access 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");
      }
  }

他的初始化和start方法就看完了, 從上面來看, AMS 可以 查看內(nèi)存情況 耗電情況 cpu 情況 并且管理者四大組件 安全策略 網(wǎng)絡(luò) 等各個服務(wù)的情況,還是非常有必要好好看一下的,

在SystemServer 初始化AMS 后,后續(xù)還調(diào)用了

mActivityManagerService.initPowerManagement();  

初始化了電量服務(wù) 之后又調(diào)用了

mActivityManagerService.setSystemProcess();

public void setSystemProcess() {
      try {
          ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
                  DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
          ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
          ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
                  DUMP_FLAG_PRIORITY_HIGH);
          ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
          ServiceManager.addService("dbinfo", new DbBinder(this));
          if (MONITOR_CPU_USAGE) {
              ServiceManager.addService("cpuinfo", new CpuBinder(this),
                      /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
          }
          ServiceManager.addService("permission", new PermissionController(this));
          ServiceManager.addService("processinfo", new ProcessInfoService(this));
          ServiceManager.addService("cacheinfo", new CacheBinder(this));

          ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                  "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
          mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());

          synchronized (this) {
              ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
                      false,
                      0,
                      new HostingRecord("system"));
              app.setPersistent(true);
              app.pid = MY_PID;
              app.getWindowProcessController().setPid(MY_PID);
              app.maxAdj = ProcessList.SYSTEM_ADJ;
              app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
              addPidLocked(app);
              mProcessList.updateLruProcessLocked(app, false, null);
              updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
          }
      } catch (PackageManager.NameNotFoundException e) {
          throw new RuntimeException(
                  "Unable to find android system package", e);
      }

      // Start watching app ops after we and the package manager are up and running.
      mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
              new IAppOpsCallback.Stub() {
                  @Override public void opChanged(int op, int uid, String packageName) {
                      if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
                          if (getAppOpsManager().checkOpNoThrow(op, uid, packageName)
                                  != AppOpsManager.MODE_ALLOWED) {
                              runInBackgroundDisabled(uid);
                          }
                      }
                  }
              });

      final int[] cameraOp = {AppOpsManager.OP_CAMERA};
      mAppOpsService.startWatchingActive(cameraOp, new IAppOpsActiveCallback.Stub() {
          @Override
          public void opActiveChanged(int op, int uid, String packageName, boolean active) {
              cameraActiveChanged(uid, active);
          }
      });
  }

在這里將他所持有的服務(wù)添加到 ServiceManager當中,這也解決了我們在看代碼過程中沒有發(fā)現(xiàn) AMS 將自己添加到ServiceManager當中的這么一個疑問

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容