Android14 - 系统启动之Launcher源码分析

1,034 阅读10分钟

系统启动的最后一步是去启动一个应用程序来显示系统中已经安装的应用程序,这个程序叫做Launcher,平时我们所说的回到系统桌面的桌面,就是Launcher的界面。

所有的应用进程都是通过Zygote进程fork而来,因此首先来看系统是如何通知Zygote进程去孵化Launcehr进程的,其次再看Launcher进程是如何显示应用图标到界面上的。

环境参数:

  • android-14.0.0_r27
  • Ubuntu 22.04.5 LTS

在线源码网址:xrefandroid

Launcher启动过程

Launcher的启动是由System Server的一部分逻辑触发的。在System Server进程中,会先后去启动各种服务:

@frameworks/base/services/java/com/android/server/SystemServer.java#run
...
try {
    t.traceBegin("StartServices");
    //启动引导服务
    startBootstrapServices(t);
    //启动核心服务
    startCoreServices(t);
    //启动其他服务
    startOtherServices(t);
    //启动Apex相关服务
    startApexServices(t);
}
...

首先在启动引导服务这一步中,启动了ActivityManagerService服务和ActivityTaskManagerService服务:

@frameworks/base/services/java/com/android/server/SystemServer.java#startBootstrapServices
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
    ...
    t.traceBegin("StartActivityManager");
    // TODO: Might need to move after migration to WM.
    ActivityTaskManagerService atm = mSystemServiceManager.startService(
            ActivityTaskManagerService.Lifecycle.class).getService();
    mActivityManagerService = ActivityManagerService.Lifecycle.startService(
            mSystemServiceManager, atm);
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    mWindowManagerGlobalLock = atm.getGlobalLock();
    t.traceEnd();
    ...
}

AMS服务启动时,会在构造方法中实例化一个内部类LocalService对象,然后在start方法中将LocalService对象添加到了LocalServices中保存:

@frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
    ...
    mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
    ...
    mInternal = new LocalService();
    ...
}
...
private void start() {
    ...
    LocalServices.addService(ActivityManagerInternal.class, mInternal);
    ...
}
...
public final class LocalService extends ActivityManagerInternal
        implements ActivityManagerLocal {
        ...
}

ATMS服务和AMS服务一样,在构造方法中实例化一个内部类LocalService对象,然后在start方法中将LocalService对象添加到了LocalServices中保存:

@frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
public ActivityTaskManagerService(Context context) {
    ...
    mInternal = new LocalService();
    ...
}
private void start() {
    LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
} 
final class LocalService extends ActivityTaskManagerInternal {
    ...
    @Override
    public boolean startHomeOnAllDisplays(int userId, String reason) {
        synchronized (mGlobalLock) {
            return mRootWindowContainer.startHomeOnAllDisplays(userId, reason);
        }
    }
    ...

}

启动Launcher的入口为AMS的systemReady方法,他在启动其他服务这一步被调用:

@frameworks/base/services/java/com/android/server/SystemServer.java#startOtherServices
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
    ...
    mActivityManagerService.systemReady(() -> {
        Slog.i(TAG, "Making services ready");
        t.traceBegin("StartActivityManagerReadyPhase");
        mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
        t.traceEnd();
        ...
    }
    ...
}

进入到AMS的systemReady方法:

@frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
...
public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
    ...
    if (isBootingSystemUser && !UserManager.isHeadlessSystemUserMode()) {
        t.traceBegin("startHomeOnAllDisplays");
        mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
        t.traceEnd();
    }
    ...
}

在AMS的systemReady方法中,mAtmInternal其实就是ATMS启动的时候向LocalServices注册的内部类ActivityTaskManagerService#LocalService,再往下会进入到RootWindowContainer的startHomeOnAllDisplays方法:

@@frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

//1
boolean startHomeOnAllDisplays(int userId, String reason) {
    boolean homeStarted = false;
    for (int i = getChildCount() - 1; i >= 0; i--) {
        final int displayId = getChildAt(i).mDisplayId;
        //调用startHomeOnDisplay方法
        homeStarted |= startHomeOnDisplay(userId, reason, displayId);
    }
    return homeStarted;
}

boolean startHomeOnDisplay(int userId, String reason, int displayId) {
    return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
            false /* fromHomeKey */);
}

boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
        boolean fromHomeKey) {
    // Fallback to top focused display or default display if the displayId is invalid.
    if (displayId == INVALID_DISPLAY) {
        final Task rootTask = getTopDisplayFocusedRootTask();
        displayId = rootTask != null ? rootTask.getDisplayId() : DEFAULT_DISPLAY;
    }

    final DisplayContent display = getDisplayContent(displayId);
    return display.reduceOnAllTaskDisplayAreas((taskDisplayArea, result) ->
                    result | startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
                            allowInstrumenting, fromHomeKey),
            false /* initValue */);
}

在注释1,startHomeOnAllDisplays方法中遍历所有的displayid,在每个display上都启动launcher。 最终会走到startHomeOnTaskDisplayArea方法:

@frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
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 Task rootTask = getTopDisplayFocusedRootTask();
        taskDisplayArea = rootTask != null ? rootTask.getDisplayArea()
                : getDefaultTaskDisplayArea();
    }
    //构建homeIntent
    Intent homeIntent = null;
    ActivityInfo aInfo = null;
    if (taskDisplayArea == getDefaultTaskDisplayArea()
            || mWmService.shouldPlacePrimaryHomeOnDisplay(
                    taskDisplayArea.getDisplayId(), userId)) {
        //如果taskDisplayArea是默认的区域,通常为主屏幕。通过ATMS获取Intent
        homeIntent = mService.getHomeIntent();
        //查找当前系统中包含android.intent.category.HOME的Activity
        //择优选择使用
        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;
    }
    //判断是否启动Home
    if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, allowInstrumenting)) {
        return false;
    }

    //更新intent的参数
    // Updates the home component of the intent.
    homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
    homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
    //如果是从HomeKey启动,需要额外添加参数
    // Updates the extra information of the intent.
    if (fromHomeKey) {
        homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);
        if (mWindowManager.getRecentsAnimationController() != null) {
            mWindowManager.getRecentsAnimationController().cancelAnimationForHomeStart();
        }
    }
    homeIntent.putExtra(WindowManagerPolicy.EXTRA_START_REASON, reason);

    //1:启动
    mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
            taskDisplayArea);
    return true;
}

注释1中mService为ATMS,getActivityStartController()方法获取ActivityStartController对象:

mActivityStartController = new ActivityStartController(this);
ActivityStartController getActivityStartController() {
   return mActivityStartController;
}

进入ActivityStartControlle的startHomeActivity方法中:

@frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
        TaskDisplayArea taskDisplayArea) {
    ...
    //1
    mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
            .setOutActivity(tmpOutRecord)
            .setCallingUid(0)
            .setActivityInfo(aInfo)
            .setActivityOptions(options.toBundle())
            .execute();
    mLastHomeActivityStartRecord = tmpOutRecord[0];
    if (rootHomeTask.mInResumeTopActivity) {
        // If we are in resume section already, home activity will be initialized, but not
        // resumed (to avoid recursive resume) and will stay that way until something pokes it
        // again. We need to schedule another resume.
        mSupervisor.scheduleResumeTopActivities();
    }
}

注释1处,通过obtainStarter方法获取ActivityStarter对象,并对其进行赋值,最后执行execute方法:

@frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
/**
 * Resolve necessary information according the request parameters provided earlier, and execute
 * the request which begin the journey of starting an activity.
 * @return The starter result.
 */
int execute() {
    try {
        ...
        int res;
        synchronized (mService.mGlobalLock) {
            ...
            try {
                res = executeRequest(mRequest);
            } finally {
                ...
            }
            ...
            return getExternalResult(res);
        }
    } 
    ...
}

ActivityStarter创建的时候传入了巨多的信息,因此execute方法里根据这些信息解析参数,是去启动activity的入口,从execute方法开始,会执行一系列的方法调用:

  • ActivityStarter#execute()
  • ActivityStarter#executeRequest() 主要是执行一系列权限检查
  • ActivityStarter#startActivityUnchecked() 主要是校验权限检查完成情况
  • ActivityStarter#startActivityInner() 主要是启动activity,并确定是否将activity添加到栈顶
  • Task#startactivitylocked() 主要是判断当前activity是否可见以及是否需要为其新建Task,并将ActivityRecord添加到Task栈顶中去
  • RootWindowContainer#resumeFocusedTasksTopActivities()主要是判断targetRootTask是否处于栈顶,同时判断Task是否处于暂停状态
  • TaskFragment#resumeTopAvtivity()
  • ActivityTaskSupervisor#startSpecificActivity()
  • ATMS#startProcessAsync()
  • AMS#startProcess()

其中在ActivityTaskSupervisor的startSpecificActivity方法中,会先去判断activity所在的进程是否存在,不存在则会首先启动进程,如果进程已经存在,则会去启动activity:

void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    final WindowProcessController wpc =
            mService.getProcessController(r.processName, r.info.applicationInfo.uid);

    boolean knownToBeDead = false;
    if (wpc != null && wpc.hasThread()) {
        try {
            //如果进程已经存在,则去启动activity
            realStartActivityLocked(r, wpc, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }

        // If a dead object exception was thrown -- fall through to
        // restart the application.
        knownToBeDead = true;
        // Remove the process record so it won't be considered as alive.
        mService.mProcessNames.remove(wpc.mName, wpc.mUid);
        mService.mProcessMap.remove(wpc.getPid());
    } else if (r.intent.isSandboxActivity(mService.mContext)) {
        Slog.e(TAG, "Abort sandbox activity launching as no sandbox process to host it.");
        r.finishIfPossible("No sandbox process for the activity", false /* oomAdj */);
        r.launchFailed = true;
        r.detachFromProcess();
        return;
    }

    r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

    final boolean isTop = andResume && r.isTopRunningActivity();
    //没有进程则去启动进程
    mService.startProcessAsync(r, knownToBeDead, isTop,
            isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY
                    : HostingRecord.HOSTING_TYPE_ACTIVITY);
}

realStartActivityLocked中,会先去通过ATMS启动事务,然后在ActivityThread的Handler类H中处理消息开始处理事务,最后依次调用ActivityThread的handleLaunchActivity()handleStartActivity()handleResumeActivity()方法去启动activity。具体如何启动activity,见后续文章。

最终会走到ZygoteProcess的startViaZygote方法去创建进程:

@frameworks/base/core/java/android/os/ZygoteProcess.java#startViaZygote
private Process.ProcessStartResult startViaZygote(@NonNull final String processClass,
                                                  @Nullable final String niceName,
                                                  final int uid, final int gid,
                                                  @Nullable final int[] gids,
                                                  int runtimeFlags, int mountExternal,
                                                  int targetSdkVersion,
                                                  @Nullable String seInfo,
                                                  @NonNull String abi,
                                                  @Nullable String instructionSet,
                                                  @Nullable String appDataDir,
                                                  @Nullable String invokeWith,
                                                  boolean startChildZygote,
                                                  @Nullable String packageName,
                                                  int zygotePolicyFlags,
                                                  boolean isTopApp,
                                                  @Nullable long[] disabledCompatChanges,
                                                  @Nullable Map<String, Pair<String, Long>>
                                                          pkgDataInfoMap,
                                                  @Nullable Map<String, Pair<String, Long>>
                                                          allowlistedDataInfoList,
                                                  boolean bindMountAppsData,
                                                  boolean bindMountAppStorageDirs,
                                                  @Nullable String[] extraArgs)
                                                  throws ZygoteStartFailedEx { 
    ...                                              
    synchronized(mLock) {
        // The USAP pool can not be used if the application will not use the systems graphics
        // driver.  If that driver is requested use the Zygote application start path.
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                          zygotePolicyFlags,
                                          argsForZygote);
    }
}

其中processClass为android.app.ActivityThread,表示其入口函数在ActivityThread中, 在openZygoteSocketIfNeeded方法中通过socket与zygote通信,通过zygote孵化出launcher进程

private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
    try {
        attemptConnectionToPrimaryZygote();

        if (primaryZygoteState.matches(abi)) {
            return primaryZygoteState;
        }

        if (mZygoteSecondarySocketAddress != null) {
            // The primary zygote didn't match. Try the secondary.
            attemptConnectionToSecondaryZygote();

            if (secondaryZygoteState.matches(abi)) {
                return secondaryZygoteState;
            }
        }
    } catch (IOException ioe) {
        throw new ZygoteStartFailedEx("Error connecting to zygote", ioe);
    }

    throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}

Launcher进程创建成功后,入口函数在ActivityThread的main方法,随后调用Looper.loop()进入循环等待处理消息。

Launcher应用图标显示

Launcher作为桌面会显示应用程序的图标,而应用程序图标是用户进入应用程序的入口,了解了Launcher进程的启动后,继续看Launcher是如何显示应用程序图标的。

Launcher应用位于packages/apps/Launcher3目录,从清单配置文件AndroidManifest.xml可知,其主activitycom.android.launcher3.Launcher,位于packages/apps/Launcher3/src/com/android/launcher3目录下。

@packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
private LauncherModel mModel;
protected void onCreate(Bundle savedInstanceState) {
    ...
    super.onCreate(savedInstanceState);
    ...
    //1
    LauncherAppState app = LauncherAppState.getInstance(this);
    //2
    mModel = app.getModel();
     ...
     //3
    if (!mModel.addCallbacksAndLoad(this)) {
        ...
    }
    setContentView(getRootView());
    ...
}

在生命周期onCreate中,注释1获取了单例LauncherAppState,然后注释2通过单例获取LauncherModel对象,最后注释3向LauncherModel对象注入依赖,可以发现的是函数addCallbacksAndLoad的参数类型为一个接口类型,因此我们可以说主activity通过单例LauncherAppState向LauncherModel注册了一个回调,LauncherModel拿到这个回调引用后,就可以在合适的时候向这个主activity通过回调接口发送消息。可以理解为观察者模式。

@packages/apps/Launcher3/src/com/android/launcher3/LauncherModel.java

private final ArrayList<Callbacks> mCallbacksList = new ArrayList<>(1);
public boolean addCallbacksAndLoad(@NonNull final Callbacks callbacks) {
    synchronized (mLock) {
        addCallbacks(callbacks);
        return startLoader(new Callbacks[] { callbacks });
    }
}

public void addCallbacks(@NonNull final Callbacks callbacks) {
    Preconditions.assertUIThread();
    synchronized (mCallbacksList) {
        mCallbacksList.add(callbacks);
    }
}

在addCallbacksAndLoad函数中,会先把注入的观察者存入一个数组保存起来,然后执行startLoader函数进入下一步:

@packages/apps/Launcher3/src/com/android/launcher3/LauncherModel.java
private boolean startLoader(@NonNull final Callbacks[] newCallbacks) {
    ...
    synchronized (mLock) {
        // If there is already one running, tell it to stop.
        boolean wasRunning = stopLoader();
        //已经加载成功并且有正在运行的事务
        boolean bindDirectly = mModelLoaded && !mIsLoaderTaskRunning;
        boolean bindAllCallbacks = wasRunning || !bindDirectly || newCallbacks.length == 0;
        final Callbacks[] callbacksList = bindAllCallbacks ? getCallbacks() : newCallbacks;

        if (callbacksList.length > 0) {
            // 先去清除待处理的绑定事件
            for (Callbacks cb : callbacksList) {
                MAIN_EXECUTOR.execute(cb::clearPendingBinds);
            }

            LauncherBinder launcherBinder = new LauncherBinder(
                    mApp, mBgDataModel, mBgAllAppsList, callbacksList);
            if (bindDirectly) {
                ...
                //直接去绑定
                launcherBinder.bindAllApps();
                launcherBinder.bindDeepShortcuts();
                launcherBinder.bindWidgets();
                if (FeatureFlags.CHANGE_MODEL_DELEGATE_LOADING_ORDER.get()) {
                    mModelDelegate.bindAllModelExtras(callbacksList);
                }
                return true;
            } else {
                stopLoader();
                mLoaderTask = new LoaderTask(
                        mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, launcherBinder);

                // Always post the loader task, instead of running directly
                // (even on same thread) so that we exit any nested synchronized blocks
                MODEL_EXECUTOR.post(mLoaderTask);
            }
        }
    }
    return false;
}

首先会先去清理之前待处理的事件,然后会根据情况去执行直接绑定数据还是先去执行加载任务,第一次进入bindDirectly为false。LoaderTask是一个Runnable类型,MODEL_EXECUTOR是一个Executor,直接看LoaderTask的run方法:

@packages/apps/Launcher3/src/com/android/launcher3/model/LoaderTask.java#run
public void run() {
    
    TraceHelper.INSTANCE.beginSection(TAG);
    LoaderMemoryLogger memoryLogger = new LoaderMemoryLogger();
    try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {
        List<ShortcutInfo> allShortcuts = new ArrayList<>();
        //加载工作区
        loadWorkspace(allShortcuts, "", memoryLogger);
        ...
        verifyNotStopped();
        //绑定工作区
        mLauncherBinder.bindWorkspace(true /* incrementBindId */, /* isBindSync= */ false);
        ...
        List<LauncherActivityInfo> allActivityList;
        try {
            //加载数据
           allActivityList = loadAllApps();
        } finally {
            Trace.endSection();
        }
        ...
        //去绑定所有的app数据
        mLauncherBinder.bindAllApps();
        ...

        mLauncherBinder.bindWidgets();
        ...
    }
}

先去处理了工作区事务,然后直接去加载所有app的数据,最后去通过LauncherBinder去绑定数据。如何加载app数据的呢?

@packages/apps/Launcher3/src/com/android/launcher3/model/LoaderTask.java#loadAllApps
private List<LauncherActivityInfo> loadAllApps() {
   final List<UserHandle> profiles = mUserCache.getUserProfiles();
   List<LauncherActivityInfo> allActivityList = new ArrayList<>();
   // Clear the list of apps
   mBgAllAppsList.clear();

   List<IconRequestInfo<AppInfo>> iconRequestInfos = new ArrayList<>();
   for (UserHandle user : profiles) {
       //mLauncherApps获取app数据
       // 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;
       }
       boolean quietMode = mUserManagerState.isUserQuiet(user);
       // Create the ApplicationInfos
       for (int i = 0; i < apps.size(); i++) {
           LauncherActivityInfo app = apps.get(i);
           AppInfo appInfo = new AppInfo(app, user, quietMode);

           iconRequestInfos.add(new IconRequestInfo<>(
                   appInfo, app, /* useLowResIcon= */ false));
           //将数据放入mBgAllAppsList里        
           mBgAllAppsList.add(
                   appInfo, app, false);
       }
       allActivityList.addAll(apps);
   }
    ...
    return allActivityList;
}

首先通过系统服务LauncherApps获取app数据列表,然后将数据放入mBgAllAppsList保存。

@packages/apps/Launcher3/src/com/android/launcher3/model/BaseLauncherBinder.java
public void bindAllApps() {
    // shallow copy
    AppInfo[] apps = mBgAllAppsList.copyData();
    int flags = mBgAllAppsList.getFlags();
    Map<PackageUserKey, Integer> packageUserKeytoUidMap = Arrays.stream(apps).collect(
            Collectors.toMap(
                    appInfo -> new PackageUserKey(appInfo.componentName.getPackageName(),
                            appInfo.user), appInfo -> appInfo.uid, (a, b) -> a));
    executeCallbacksTask(c -> c.bindAllApplications(apps, flags, packageUserKeytoUidMap),
            mUiExecutor);
}

protected void executeCallbacksTask(CallbackTask task, Executor executor) {
        executor.execute(() -> {
            if (mMyBindingId != mBgDataModel.lastBindId) {
                Log.d(TAG, "Too many consecutive reloads, skipping obsolete data-bind");
                return;
            }
            for (Callbacks cb : mCallbacksList) {
                task.execute(cb);
            }
        });
}

LauncherBinder的基类就是BaseLauncherBinder,在bindAllApps调用时,主要就是将app的列表数据下发到之前注册的观察者,比如Launcher,在Launcher中找到bindAllApplication方法:

@packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

mAppsView = findViewById(R.id.apps_view);
@Override
@TargetApi(Build.VERSION_CODES.S)
@UiThread
public void bindAllApplications(AppInfo[] apps, int flags,
        Map<PackageUserKey, Integer> packageUserKeytoUidMap) {
    Preconditions.assertUIThread();
    boolean hadWorkApps = mAppsView.shouldShowTabs();
    AllAppsStore<Launcher> appsStore = mAppsView.getAppsStore();
    //传递数据
    appsStore.setApps(apps, flags, packageUserKeytoUidMap);
    ...
}

继续分析Launcher的bindAllApplications()方法被调用收到数据时,mAppsView是Launcher的视图容器,将app列表数据存入到了AllAppsStore类型的对象里,该对象是在视图容器mAppsView创建的。

@packages/apps/Launcher3/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
public ActivityAllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    mActivityContext = ActivityContext.lookupContext(context);
    //实例化
    mAllAppsStore = new AllAppsStore<>(mActivityContext);

    ...
    //添加回调
    AllAppsStore.OnUpdateListener onAppsUpdated = this::onAppsUpdated;
    mAllAppsStore.addUpdateListener(onAppsUpdated);
    ...
}

//将被调用的函数
private void onAppsUpdated() {
    mHasWorkApps = Stream.of(mAllAppsStore.getApps()).anyMatch(mWorkManager.getMatcher());
    if (!isSearching()) {
        rebindAdapters();
        if (mHasWorkApps) {
            mWorkManager.reset();
        }
    }

    mActivityContext.getStatsLogManager().logger()
            .withCardinality(mAllAppsStore.getApps().length)
            .log(LAUNCHER_ALLAPPS_COUNT);
}

在创建的同时注册了一个回调函数onAppsUpdated,而在向appstore传递数据后,会调用这个回调提醒试图更新数据。

@packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsStore.java
public void setApps(@Nullable AppInfo[] apps, int flags, Map<PackageUserKey, Integer> map)  {
   mApps = apps == null ? EMPTY_ARRAY : apps;
   mModelFlags = flags;
   notifyUpdate();
   ...
}


private void notifyUpdate() {
    if (mDeferUpdatesFlags != 0) {
        mUpdatePending = true;
        return;
    }
    for (OnUpdateListener listener : mUpdateListeners) {
        listener.onAppsUpdated();
    }
}

后面就是通过rebindAdapters函数去操作recyclerview更新界面。

以上过程可用以下图概括:

  • Launcher向LauncheModel注册回调,保存在mCallbackList列表里,
  • 在LauncherModel中创建LoadeTask对象,通过loadAllApps()方法去加载app数据,存放在mBgAllAppsList对象里面(数据来源自系统服务LauncherApps)
  • 调用launcherBinder对象的bindAllApps()方法,将mBgAllAppsList里面的app数据通过mCallbackList调用bindAllApplications()函数分发出去
  • 此时Launcher收到app列表数据,将数据下发给AllAppsStore,然后在回调给容器视图类ActivityAllAppsContainerView,显示在界面上。

总结:系统启动时,Launcher的启动最开始由SystemServer触发,在AMS中发起,经过ATMS,最后通过socket的方式通知zygote孵化进程,然后加载Launcher的资源,启动主activity-Launcher。桌面launcher的数据来源自系统服务LauncherApps,通过recyclerview的方式显示出来。