Inicio del sistema Android: proceso de inicio

Este código fuente se basa en el análisis de Android11

Código fuente relacionado:

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
/frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
/packages/apps/Launcher3/src/com/android/launcher3/LauncherModel.java
/packages/apps/Launcher3/src/com/android/launcher3/model/LoaderTask.java

复制代码

En el artículo anterior, se explicó que los servicios del sistema ActivityManagerService (ActivityTaskManagerService) y PackageManagerService se iniciaron en los métodos **startBootstrapServices() y startOtherServices()** del proceso SystemServer .

  1. ActivityManagerService: Principal responsable de la creación y gestión de los cuatro componentes principales.
  2. PackageManagerService: Es el principal responsable de la consulta, instalación y desinstalación de paquetes de instalación.

El Lanzador de procesos de escritorio del sistema se inicia después de iniciar el servicio ActivityManagerService .

Comienza el proceso del lanzador

ActivityManagerService.systemReadyEl método inicia el lanzamiento del proceso Launcher

public class ActivityManagerService extends IActivityManager.Stub
      implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

  // mAtmInternal为ActivityTaskManagerService.LocalService类
  public ActivityTaskManagerInternal mAtmInternal;

  // ActivityManagerService准备完成
  public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {

      // 调用启动Launcher进程
      mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
  }
}

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
  RootWindowContainer mRootWindowContainer;

  final class LocalService extends ActivityTaskManagerInternal {
      @Override
      public boolean startHomeOnAllDisplays(int userId, String reason) {
          synchronized (mGlobalLock) {
              return mRootWindowContainer.startHomeOnAllDisplays(userId, reason);
          }
      }

  }
}
复制代码
  1. El proceso Launcher se inicia en el método systemReady de AMS, pero el proceso no se inicia realmente. Esto es solo un comienzo, y luego ActivityTaskManagerService.LocalServiceel método startHomeOnAllDisplays de la clase continúa ejecutándose.
  2. No hay procesamiento en ActivityTaskManagerService, pero RootWindowContainer.startHomeOnAllDisplaysse llama al procesamiento del método.

RootWindowContainer.startHomeOnAllDisplaysEl método finalmente se llama a través de una serie de llamadas RootWindowContainer.startHomeOnTaskDisplayArea:

class RootWindowContainer extends WindowContainer<DisplayContent>
      implements DisplayManager.DisplayListener {

  ActivityTaskManagerService mService;

  boolean startHomeOnAllDisplays(int userId, String reason) {
      boolean homeStarted = false;
      // getChildCount获取显示设备数目,这个主要从mChildren参数中获取对应的数量
      // mChildren是一个WindowList的一个对象,其包含的数据是在setWindowManager函数被调用时,从DisplayManagerService中获取到的Display的数目
      for (int i = getChildCount() - 1; i >= 0; i--) {
          // 获取到对应新建的DisplayContent的displayId
          final int displayId = getChildAt(i).mDisplayId;
          // 调用startHomeOnDisplay函数
          homeStarted |= startHomeOnDisplay(userId, reason, displayId);

      }
      return homeStarted;

  }
  //一系列调用最终调用startHomeOnTaskDisplayArea.......

  boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
                                     boolean allowInstrumenting, boolean fromHomeKey) {
      // Fallback to top focused display area if the provided one is invalid.
      if (taskDisplayArea == null) {
          final ActivityStack stack = getTopDisplayFocusedStack();
          taskDisplayArea = stack != null ? stack.getDisplayArea()
                  : getDefaultTaskDisplayArea();
      }

      Intent homeIntent = null;
      ActivityInfo aInfo = null;
      if (taskDisplayArea == getDefaultTaskDisplayArea()) {
          // 1.向ActivityTaskManagerService获取 Launcher 的启动意图
          homeIntent = mService.getHomeIntent();
          //2. 向PackageManagerService通过意图解析到 ActivityInfo
          aInfo = resolveHomeActivity(userId, homeIntent);
      } else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
          Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
          aInfo = info.first;
          homeIntent = info.second;
      }
      if (aInfo == null || homeIntent == null) {
          return false;
      }

      if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, allowInstrumenting)) {
          return false;
      }

      // Updates the home component of the intent.
      homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
      homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
      // Updates the extra information of the intent.
      if (fromHomeKey) {
          homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
          mWindowManager.cancelRecentsAnimation(REORDER_KEEP_IN_PLACE, "startHomeActivity");
      }
      // Update the reason for ANR debugging to verify if the user activity is the one that
      // actually launched.
      final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(
              aInfo.applicationInfo.uid) + ":" + taskDisplayArea.getDisplayId();

      // 根据homeIntent、aInfo,调用 startHomeActivity 方法去启动和创建 Launcher
      mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
              taskDisplayArea);
      return true;
  }

  // 根据Intent的Component向PackageManagerService找到对应的ActivityInfo
  ActivityInfo resolveHomeActivity(int userId, Intent homeIntent) {
      final int flags = ActivityManagerService.STOCK_PM_FLAGS;
      final ComponentName comp = homeIntent.getComponent();
      ActivityInfo aInfo = null;
      try {
          if (comp != null) {
              // Factory test.
              aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
          } else {
              final String resolvedType =
                      homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver());
              final ResolveInfo info = AppGlobals.getPackageManager()
                      .resolveIntent(homeIntent, resolvedType, flags, userId);
              if (info != null) {
                  aInfo = info.activityInfo;
              }
          }
      } catch (RemoteException e) {
          // ignore
      }

      if (aInfo == null) {
          Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable());
          return null;
      }

      aInfo = new ActivityInfo(aInfo);
      aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId);
      return aInfo;
  }

}



public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
  String mTopAction = Intent.ACTION_MAIN;
  String mTopData;

  // homeIntent.action = Intent.ACTION_MAIN   ACTION_MAIN = "android.intent.action.MAIN"
  // homeIntent的flags包含Intent.FLAG_DEBUG_TRIAGED_MISSING
  // homeIntent的category包含Intent.CATEGORY_HOME  CATEGORY_HOME = "android.intent.category.HOME";
  Intent getHomeIntent() {
      Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
      intent.setComponent(mTopComponent);
      intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
      if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
          intent.addCategory(Intent.CATEGORY_HOME);
      }
      return intent;
  }

}
复制代码

El código es largo, pero hace dos cosas:

  • Llame al método ActivityTaskManagerService.getHomeIntent para obtener la intención Intent
  • Consulte la información de actividad correspondiente del PackageManagerService de acuerdo con la intención Intent.Component

Finalmente, a través del método ActivityStartController.startHomeActivity, Process.startse llama al último método de llamada a través de capas para iniciar y crear el Launcher. El siguiente artículo explica la creación del proceso posterior y el inicio de la Actividad.Este artículo continúa analizando cómo consultar toda la información de la aplicación después de que se inicie el Lanzador.

Lanzador para consultar información de la aplicación

En LauncherActividad, onCreatetoda la información de la aplicación se consultará en el método:

public class Launcher extends StatefulActivity<LauncherState> implements LauncherExterns,
      Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin> {

  @Override
  protected void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      // 实例化LauncherAppState
      LauncherAppState app = LauncherAppState.getInstance(this);
      // 根据LauncherAppState获取到LauncherModel
      mModel = app.getModel();

      // LauncherModel.addCallbacksAndLoad就会去查询App信息
      if (!mModel.addCallbacksAndLoad(this)) {
          if (!internalStateHandled) {
              // If we are not binding synchronously, show a fade in animation when
              // the first page bind completes.
              mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD).setValue(0);
          }
      }

  }
}
复制代码

Consulta la información de la aplicación llamando a onCreate LauncherModel.addCallbacksAndLoad, este método ejecuta un Runnable a través de un controlador para ejecutar la tarea de consulta.

public class LauncherModel extends LauncherApps.Callback implements InstallSessionTracker.Callback {

  // Launcher也实现了Callbacks
  public boolean addCallbacksAndLoad(Callbacks callbacks) {
      synchronized (mLock) {
          // 将Launcher加入到回调列表
          addCallbacks(callbacks);
          // 调用startLoader()
          return startLoader();
      }
  }

  public boolean startLoader() {
      synchronized (mLock) {
          //.....
          stopLoader();
          LoaderResults loaderResults = new LoaderResults(
                  mApp, mBgDataModel, mBgAllAppsList, callbacksList, mMainExecutor);
          // 开始查询App信息
          startLoaderForResults(loaderResults);
          return false;
      }
  }

  public void startLoaderForResults(LoaderResults results) {
      synchronized (mLock) {
          stopLoader();
          // LoaderTask是一个Runnable
          mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, mBgDataModel, results);

          // Handler去执行LoaderTask
          MODEL_EXECUTOR.post(mLoaderTask);
      }
  }

}
复制代码

Al mirar el código clave, LauncherModel simplemente envía un LoaderTaskRunnable para que lo ejecute el controlador. Entonces, la aplicación de consulta está en LoaderTaskel método run() de la clase.

public class LoaderTask implements Runnable {

  public void run() {
      //.....

      // 加载所有App
      List<LauncherActivityInfo> allActivityList = loadAllApps();

      //.....
  }
  
  // 查询所有App
  private List<LauncherActivityInfo> loadAllApps() {
      final List<UserHandle> profiles = mUserCache.getUserProfiles();
      List<LauncherActivityInfo> allActivityList = new ArrayList<>();
      // Clear the list of apps
      mBgAllAppsList.clear();
      for (UserHandle user : profiles) {
          // Query for the set of apps
          final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
          // Fail if we don't have any apps
          // TODO: Fix this. Only fail for the current user.
          if (apps == null || apps.isEmpty()) {
              return allActivityList;
          }
          //....
          allActivityList.addAll(apps);
      }
      //.....
      return allActivityList;
  }


}

public class LauncherApps {

  public List<LauncherActivityInfo> getActivityList(String packageName, UserHandle user) {
      logErrorForInvalidProfileAccess(user);
      try {
          return convertToActivityList(mService.getLauncherActivities(mContext.getPackageName(),
                  packageName, user), user);
      } catch (RemoteException re) {
          throw re.rethrowFromSystemServer();
      }
  }
}
复制代码

El método de ejecución de LoaderTask consultará la información de todas las aplicaciones.

Resumir

Launcher es el proceso de escritorio del sistema. Se ActivityManagerServiceinicia después de que se completa la preparación. Al iniciar, obtendrá la intención de la intención de ActivityManagerService y la información de actividad correspondiente de PackageManagerService. Después de que comience la actividad del iniciador, consultará toda la información de la aplicación en el método onCreate().

Supongo que te gusta

Origin juejin.im/post/7086266564520968205
Recomendado
Clasificación