Launcher的配置

Launcher 的配置

在 SystemServer.startOtherServices 方法中调用ActivityManagerService.systemReady方法
Launcher 进程的启动就是从这里开始的,以下是相关源码:

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

以下是 ActivityManagerService.systemReady 方法的源码:

// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public ActivityTaskManagerInternal mAtmInternal;
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
    ...
    // 启动HomeActivity,即Launcher应用的入口Activity,
    // 这里指的是在所有屏幕上启动Launcher。因为 Android 10开始支持多屏幕,比如手机屏幕、虚拟投屏、外接屏幕
    mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); // 1
    ...
}

这里的mAtmInternal是ActivityTaskManagerInternal的实例,ActivityTaskManagerInternal 是一个抽象类。 ActivityManagerService中的内部类LocalService实现了ActivityTaskManagerInternal :

// /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
final class LocalService extends ActivityTaskManagerInternal {
    ...
    @Override
    public boolean startHomeOnAllDisplays(int userId, String reason) {
        synchronized (mGlobalLock) {
            return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);
        }
    }
    ...
}

在 LocalService.startHomeOnAllDisplays 方法中调用了RootActivityContainer.startHomeOnAllDisplays 方法。
RootActivityContainer 的作用是,调用PackageManagerService中去查询系统中已经安装的应用哪一个符合Launcher 标准,且返回一个Intent对象,并且交给ActivityStarter :

// /frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean startHomeOnAllDisplays(int userId, String reason) {
    boolean homeStarted = false;
    for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
        final int displayId = mActivityDisplays.get(i).mDisplayId;
        // 1
        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) {
    ...
    Intent homeIntent = null;
    ActivityInfo aInfo = null;
    if (displayId == DEFAULT_DISPLAY) {
        // 2 构建一个 category 为 CATEGORY_HOME 的 Intent,表明是 HomeActivity
        homeIntent = mService.getHomeIntent(); 
        // 3 通过 PMS 从系统所有已安装的引用中找到一个符合 homeIntent 的 Activity
        aInfo = resolveHomeActivity(userId, homeIntent);
    } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
        ...
    }
    ...
    // 4 启动 Launcher
    mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, 
                                                            myReason, displayId);
    return true;
}

在注释 2 处调用了 ActivityTaskManagerService.getHomeIntent() 方法来构建一个 category 为 CATEGORY_HOME 的 Intent,表明是一个符合 Launcher 应用的 Intent。
在注释 3 处通过调用 resolveHomeActivity 方法解析出需要启动 Activity 的信息。
在注释 4 处调用 ActivityTaskManagerService.getActivityStartController() 获取 ActivityStartController,这个类的作用就是做启动前的各项检查,比如,Activity 是否有清单文件注册,Class 文件是否存在等,之后启动 Activity。


首先,看一下 ActivityTaskManagerService的getHomeIntent() 方法,主要是构建一个符合 Launcher 应用的 Intent:

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) {
        // 1 Category
        intent.addCategory(Intent.CATEGORY_HOME); 
    }
    return intent;
}

在注释 1 处代表的是要启动 Activity 的意图,通常来说,整个系统只会有一个应用在清单文件中配置 CATEGORY_HOME,如果配置了多个,系统在启动的时候就会要求用户手动去选择哪一个应用作为启动应用,如果在系统设置应用中进行配置了,就会选择配置的那个应用。

接着看 RootActivityContainer.resolveIntentInternal 方法:

// /frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
                                          int flags, int userId, 
                                          boolean resolveForStart, 
                                          int filterCallingUid) {
    try {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");

        if (!sUserManager.exists(userId)) return null;
        final int callingUid = Binder.getCallingUid();
        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart);
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                                                      false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");

        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
        final List query = queryIntentActivitiesInternal(intent, resolvedType,
                                                                      flags, filterCallingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

        final ResolveInfo bestChoice =
            chooseBestActivity(intent, resolvedType, flags, query, userId);
        return bestChoice;
    } finally {
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    }
}

通过 Binder 跨进程通信通知 PackageManagerService 从系统所有已经安装的应用中找到一个符合 homeInent 的Activity。
再看 ActivityStartController.startHomeActivity 的代码:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, 
                       int displayId) {
    final ActivityOptions options = ActivityOptions.makeBasic();
    options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
    if (!ActivityRecord.isResolverActivity(aInfo.name)) {
        options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
    }
    options.setLaunchDisplayId(displayId);
    // 1 obtainStarter
    mLastHomeActivityStartResult = 
        obtainStarter(intent, "startHomeActivity: " + reason) 
        .setOutActivity(tmpOutRecord)
        .setCallingUid(0)
        .setActivityInfo(aInfo)
        .setActivityOptions(options.toBundle())
        .execute(); // 2
    mLastHomeActivityStartRecord = tmpOutRecord[0];
    final ActivityDisplay display =
        mService.mRootActivityContainer.getActivityDisplay(displayId);
    final ActivityStack homeStack = display != null ? display.getHomeStack() : null;
    if (homeStack != null && homeStack.mInResumeTopActivity) { 
        mSupervisor.scheduleResumeTopActivities();
    }
}

// 3
ActivityStarter obtainStarter(Intent intent, String reason) { 
    return mFactory.obtain().setIntent(intent).setReason(reason);
}

在注释 1 处先获取一个 ActivityStarter ,主要用于启动 Activity,然后把需要的参数设置进去,最后再调用它的 execute() 方法:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {
    try {
        if (mRequest.mayWait) {
           ...
        } else {
            return startActivity(...);
        }
    } finally {
        onExecutionComplete();
    }
}

以下是 ActivityStarter.startActivity 的相关源码,这个方法主要是用来做 Activity 启动之前的安全校验:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivityUnchecked(final ActivityRecord r, 
                                   ActivityRecord sourceRecord, 
                                   IVoiceInteractionSession voiceSession, 
                                   IVoiceInteractor voiceInteractor, int startFlags, 
                                   boolean doResume, ActivityOptions options, 
                                   TaskRecord inTask, ActivityRecord[] outActivity, 
                                   boolean restrictedBgActivity) {
    ...
    final int preferredWindowingMode = mLaunchParams.mWindowingMode;
    computeLaunchingTaskFlags(); // 1
    computeSourceStack(); // 2
    mIntent.setFlags(mLaunchFlags);
    ActivityRecord reusedActivity = getReusableIntentActivity();
    ...
    // 3
    mRootActivityContainer.resumeFocusedStacksTopActivities(); 
    ...
}

注释 1 处的 ActivityStarter.computeLaunchingTaskFlags() 方法是根据 Activity 的 launcher mode 和 intent.flag 计算出 Activity 的入栈方式。注释 2 处的 ActivityStarter.computeSourceStack() 计算从哪个栈中启动该 Activity。注释 3 处调用了 RootActivityContainer.resumeFocusedStacksTopActivities 方法:

// /frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean resumeFocusedStacksTopActivities() {
    return resumeFocusedStacksTopActivities(null, null, null);
}

boolean resumeFocusedStacksTopActivities(
    ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    ...
    if (targetStack != null && (targetStack.isTopStackOnDisplay()
                                || getTopDisplayFocusedStack() == targetStack)) {
        result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }

    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        ...
        if (!resumedOnDisplay) {
            final ActivityStack focusedStack = display.getFocusedStack(); 
            if (focusedStack != null) {
                // 1
                focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions); 
            }
        }
    }
    return result;
}

在注释 1 处调用 ActivityStack.resumeTopActivityUncheckedLocked 方法:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
@GuardedBy("mService")
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    ...
    result = resumeTopActivityInnerLocked(prev, options);
    ...
}

@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, 
                                             ActivityOptions options) {
    ...
    if (anim) {
        next.applyOptionsLocked();
    } else {
        next.clearOptionsLocked();
    }
    mStackSupervisor.mNoAnimActivities.clear();
    // 待启动的进程是否创建完成,如果没有就会到 else 中
    if (next.attachedToProcess()) { 
        ...
    }  else {
        // 1
         mStackSupervisor.startSpecificActivityLocked(next, true, true); 
    }
    ...
}

在注释 1 处调用 ActivityStackSupervisor.startSpecificActivityLocked:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r, boolean andResume,
                                 boolean checkConfig) {
    ...
    try {
        ...
        final Message msg = PooledLambda.obtainMessage(
            ActivityManagerInternal::startProcess,  // 1
            mService.mAmInternal, r.processName, r.info.applicationInfo, 
            knownToBeDead, "activity", r.intent.getComponent());
        mService.mH.sendMessage(msg);
    } finally {
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
}

注释 1 出调用的其实是 ActivityManagerService.startProcess 方法,开始创建进程:

// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final class LocalService extends ActivityManagerInternal {
    @Override
    public void startProcess(String processName, ApplicationInfo info,
                             boolean knownToBeDead, String hostingType, 
                             ComponentName hostingName) {
        try {
            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
                                 + processName);
            }
            synchronized (ActivityManagerService.this) {
                startProcessLocked(processName, info, knownToBeDead, 
                                   0 /* intentFlags */,
                                   new HostingRecord(hostingType, hostingName),
                                   false /* allowWhileBooting */, 
                                   false /* isolated */,
                                   true /* keepIfLarge */); // 1
            }
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

    @GuardedBy("this")
    final ProcessRecord startProcessLocked(String processName,
                                           ApplicationInfo info, 
                                           boolean knownToBeDead, int intentFlags,
                                           HostingRecord hostingRecord, 
                                           boolean allowWhileBooting, 
                                           boolean isolated, boolean keepIfLarge) {
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, 
                                               intentFlags,
                                               hostingRecord, allowWhileBooting, 
                                               isolated, 0 /* isolatedUid */, 
                                               keepIfLarge,
                                               null /* ABI override */, 
                                               null /* entryPoint */, 
                                               null /* entryPointArgs */,
                                               null /* crashHandler */); // 2
    }
}

在注释 1 处调用 LocalService.startProcessLocked 方法。在 LocalService.startProcessLocked 方法中又把进程创建的工作委派给了 ProcessList。接着看 ProcessList.startProcessLocked 方法:

// /frameworks/base/services/core/java/com/android/server/am/ProcessList.java
@GuardedBy("mService")
final void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord) {
    startProcessLocked(app, hostingRecord, null /* abiOverride */);
}

@GuardedBy("mService")
final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
                                 String abiOverride) {
    return startProcessLocked(app, hostingRecord, false /* disableHiddenApiChecks */,
                              false /* mountExtStorageFull */, abiOverride);
}

@GuardedBy("mService")
boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
                           boolean disableHiddenApiChecks, 
                           boolean mountExtStorageFull,
                           String abiOverride) {
    ...
    final String entryPoint = "android.app.ActivityThread"; // 1
    return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                              runtimeFlags, mountExternal, seInfo, requiredAbi, 
                              instructionSet, invokeWith, startTime);
}

@GuardedBy("mService")
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
                                       boolean knownToBeDead, int intentFlags, 
                                       HostingRecord hostingRecord,
                                       boolean allowWhileBooting, boolean isolated, 
                                       int isolatedUid, boolean keepIfLarge,
                                       String abiOverride, String entryPoint, 
                                       String[] entryPointArgs, Runnable crashHandler) {
    if (!isolated) {
        app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
        checkSlow(startTime, "startProcess: after getProcessRecord");
        ...
    }
    final String entryPoint = "android.app.ActivityThread";
    ...
}

这几个方法的作用是在进程创建之前,配置一些必要的参数,比如版本号之类的参数。在注释 1 处是一个非常重要的参数,entryPoint 是新进程的入口。所以,Android 应用的程序入口是 ActivityThread。
创建进程所需的参数配置完成后,最终会走到 ZygoteProcess 类中:

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,
            boolean useUsapPool,
            @Nullable String[] extraArgs) throws ZygoteStartFailedEx {

    synchronized (mLock) {
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                          useUsapPool, argsForZygote);
    }
}

此时还处于 system_server进程,这个类的目的是创建本地的 Socket 连接对象,连接到 Zygote 进程的 Socket 方法,然后通过字符输入流,把创建进程所需要的参数发送过去。



本站内容来源于作者发布和网络转载,如有版权相关问题请及时与我们取得联系,我们将立即删除。

 关于作者
 热门教程
系统启动流程
1、BootRom 启动电源以及系统启动。 当电源按下时,引导芯片代码从预定义的地方(固化在ROM中)开始执行。加载引
2023-09-10
剑道仙尊
54
Android源码开始
Framework源码下载: https://android.googlesource.com/platform/fr
2023-09-10
剑道仙尊
55
Launcher的Activity.onCreate
进入 ActivityThread.main,最终完成 Launcher.onCreate 操作 Zygote for
2022-09-11
剑道仙尊
41
Launcher启动流程
Launcher介绍 系统启动的最后一步是启动一个应用程序来显示系统中已经安装的应用程序,这个应用程序就叫做 Laun
2022-09-11
剑道仙尊
43
创建Launcher进程
Zygote进程接收请求并创建 Launcher进程 想要启动一个应用程序,首先要保证这个应用程序所需要的应用程序进程
2022-09-11
剑道仙尊
45
Launcher的配置
Launcher 的配置 在 SystemServer.startOtherServices 方法中调用Activit
2022-09-11
剑道仙尊
45
PackageManagerService
PackageManagerService( PMS ) 1、PMS会把每个apk进行扫描,然后分别把每个apk里的信
2022-09-11
剑道仙尊
42
WindowManagerService
待更新。。。
2022-09-11
剑道仙尊
27
ActivityManagerService
ActivityManagerService(AMS)主要负责系统中四大组件的启动、切换、调度以及应用程序的管理和调度
2022-09-11
剑道仙尊
51
systemserver进程
system server进程是由zygote进程fork出来的,在上面的ZygoteInit.main方法中调用fo
2022-09-10
剑道仙尊
33