Android系统启动(四) — Launcher 启动过程

这篇具有很好参考价值的文章主要介绍了Android系统启动(四) — Launcher 启动过程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 Launcher 概述

系统启动的最后一步是启动一个应用程序来显示系统中已经安装的应用程序,这个应用程序就叫做 LauncherLauncher 在启动过程中会请求 PackageManagerService 返回系统中已经安装的应用程序信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上,这样用户就可以通过点击这些快捷图标来启动相应的应用程序。

通俗的讲,Launcher 就是 Android 系统的桌面, 它的作用主要有以下两点:

  • 作为 Android 系统的启动器,用于启动应用程序;
  • 作为 Android 系统的桌面,用于显示和管理应用程序的快捷图标或者其他桌面组件;

2 Launcher 启动过程

SystemServer 进程在启动的过程中会启动 PackageManagerServicePackageManagerService 启动后会将系统中的应用程序安装完成,在此之前已经启动的 ActivityManagerService 会将 Launcher 启动起来。

Launcher 的启动分为三个部分:

  • SystemServer 完成启动 Launcher Activity 的相关配置;
  • Zygote 进程 forkLauncher 进程;
  • 进入 ActivityThread.main 函数,最终完成 LauncherActivity.onCreate 操作;
第一阶段 完成 Launcher 的相关配置

Android系统启动(四) — 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) {
    ...
    // 启动 Home Activity,即 Launcher 应用的入口 Activity,这里指的是,在所有屏幕上启动 Launcher。因为 Android 10 开始支持多屏幕,比如手机屏幕、虚拟投屏、外接屏幕
    mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); // 1
    ...
}

这里的 mAtmInternalActivityTaskManagerInternal 的实例,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;
        homeStarted |= startHomeOnDisplay(userId, reason, displayId); // 1
    }
    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) {
        // 构建一个 category 为 CATEGORY_HOME 的 Intent,表明是 HomeActivity
        homeIntent = mService.getHomeIntent(); // 2
        // 通过 PMS 从系统所有已安装的引用中找到一个符合 homeIntent 的 Activity
        aInfo = resolveHomeActivity(userId, homeIntent); // 3
    } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {
        ...
    }
    ...
    // 启动 Launcher
    mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, 
                                                            myReason, displayId); // 4
    return true;
}

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

以下是相关的时序图:

Android系统启动(四) — Launcher 启动过程

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

// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
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); // 1
    }
    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<ResolveInfo> 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 从系统所有已经安装的应用中找到一个符合 homeInentActivity

再看 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);
    mLastHomeActivityStartResult = 
        obtainStarter(intent, "startHomeActivity: " + reason) // 1
        .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();
    }
}

ActivityStarter obtainStarter(Intent intent, String reason) { // 3
    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 startActivity(...) {
    mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
    int err = ActivityManager.START_SUCCESS;
    // Pull the optional Ephemeral Installer-only bundle out of the options early.
    final Bundle verificationBundle
        = options != null ? options.popAppVerificationBundle() : null;
    WindowProcessController callerApp = null;
    if (caller != null) {
        callerApp = mService.getProcessController(caller);
        if (callerApp != null) {
            callingPid = callerApp.getPid();
            callingUid = callerApp.mInfo.uid;
        } else {
            Slog.w(TAG, "Unable to find app for caller " + caller
                   + " (pid=" + callingPid + ") when starting: "
                   + intent.toString());
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }
	...
    final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, 
                                  startFlags, true /* doResume */, checkedOptions, 
                                  inTask, outActivity, restrictedBgActivity);
    ...
}

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, 
                          IVoiceInteractionSession voiceSession, 
                          IVoiceInteractor voiceInteractor, int startFlags, 
                          boolean doResume, ActivityOptions options, 
                          TaskRecord inTask, ActivityRecord[] outActivity,
                          boolean restrictedBgActivity) {
    ...
    result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, 
                                    startFlags, doResume, options, inTask, 
                                    outActivity, restrictedBgActivity); // 1
    ...
}

注释 1 处调用了 ActivityStarter.startActivityUnchecked 的代码:

// /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();
	...
    mRootActivityContainer.resumeFocusedStacksTopActivities(); // 3
    ...
}

注释 1 处的 ActivityStarter.computeLaunchingTaskFlags() 方法是根据 Activitylauncher modeintent.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) {
                focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions); // 1
            }
        }
    }

    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();
    
    if (next.attachedToProcess()) { // 待启动的进程是否创建完成,如果没有就会到 else 中
        ...
    }  else {
         mStackSupervisor.startSpecificActivityLocked(next, true, true); // 1
    }
    ...
}

在注释 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 方法,然后通过字符输入流,把创建进程所需要的参数发送过去。

第二阶段:Zygote 进程接收请求并创建 Launcher 进程

参考 应用程序进程启动过程

第三个阶段:进入 ActivityThread.main,最终完成 Launcher.onCreate 操作

Zygote fork 出了 Launcher 进程,并把接下来的 Launcher 启动任务交给了 ActivityThread 来进行,接下来就从 ActivityThread.main 方法来分析 Launcher 的创建过程。 以下是 ActivityThread 启动 Activity 的时序图:

Android系统启动(四) — Launcher 启动过程

ActivityThread.main 方法是程序入口,以下是相关代码:

// /frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
    ...
    Looper.prepareMainLooper();
	...
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq); // 1

    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }
	...  
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

在注释 1 处调用 ActivityThread.attach 方法,以下是相关源码:

// /frameworks/base/core/java/android/app/ActivityThread.java
@UnsupportedAppUsage
private void attach(boolean system, long startSeq) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        ...
        final IActivityManager mgr = ActivityManager.getService(); // 1
        try {
            mgr.attachApplication(mAppThread, startSeq); // 2
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        ...
    } else {
        ...
    }
    ...
}

在注释 1 处获取 ActivityManagerService 的实例,在注释 2 处调用 ActivityManagerService.attachApplication 方法:

// /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
    if (thread == null) {
        throw new SecurityException("Invalid application interface");
    }
    synchronized (this) {
        // 通过 Binder 获取传入的 pid 信息
        int callingPid = Binder.getCallingPid(); 
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid, callingUid, startSeq); // 1
        Binder.restoreCallingIdentity(origId);
    }
}

public ActivityTaskManagerInternal mAtmInternal;
@GuardedBy("this")
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
                                        int pid, int callingUid, long startSeq) {
    ...
    didSomething = mAtmInternal.attachApplication(app.getWindowProcessController()); // 2
    ...
}

在注释 1 处调用了 ActivityManagerService.attachApplicationLocked 方法。注释 2 处的 mAtmInternalActivityTaskManagerInternal 类型的变量, ActivityTaskManagerService 中的内部类 LocalService 继承自 ActivityTaskManagerInternal,以下是相关源码:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
final class LocalService extends ActivityTaskManagerInternal {
    @HotPath(caller = HotPath.PROCESS_CHANGE)
    @Override
    public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
        synchronized (mGlobalLockWithoutBoost) {
            return mRootActivityContainer.attachApplication(wpc); // 1
        }
    }
}

在注释 1 处调用了 RootActivityContainer.attachApplication 方法:

// frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean attachApplication(WindowProcessController app) throws RemoteException {
    final String processName = app.mName;
    boolean didSomething = false;
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        final ActivityDisplay display = mActivityDisplays.get(displayNdx);
        final ActivityStack stack = display.getFocusedStack();
        if (stack != null) {
            stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
            final ActivityRecord top = stack.topRunningActivityLocked();
            final int size = mTmpActivityList.size();
            for (int i = 0; i < size; i++) {
                final ActivityRecord activity = mTmpActivityList.get(i);
                if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
                    && processName.equals(activity.processName)) {
                    try {
                        // 1
                        if (mStackSupervisor.realStartActivityLocked(activity, app,
                                                            top == activity /* andResume */, 
                                                                     true /* checkConfig */)) {
                            didSomething = true;
                        }
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Exception in new application when starting activity "
                               + top.intent.getComponent().flattenToShortString(), e);
                        throw e;
                    }
                }
            }
        }
    }
    if (!didSomething) {
        ensureActivitiesVisible(null, 0, false /* preserve_windows */);
    }
    return didSomething;
}

在注释 1 处调用 ActivityStackSupervisor.realStartActivityLocked 方法:

// /frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
                                boolean andResume, boolean checkConfig) throws RemoteException {
	...
    clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                         System.identityHashCode(r), r.info,  
                         mergedConfiguration.getGlobalConfiguration(),
                         mergedConfiguration.getOverrideConfiguration(), r.compat,
                         r.launchedFromPackage, task.voiceInteractor,             
                         proc.getReportedProcState(), r.icicle, r.persistentState, results, 
                         newIntents, dc.isNextTransitionForward(),
                         proc.createProfilerInfoIfNeeded(), r.assistToken)); // 1

	...
    // Schedule transaction.
    mService.getLifecycleManager().scheduleTransaction(clientTransaction); // 2 
	...
}

注释 2ActivityTaskManagerService.getLifecycleManager 方法返回 ClientLifecycleManager 实例。以下是 ClientLifecycleManager.scheduleTransaction 的相关源码:

// /frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    final IApplicationThread client = transaction.getClient();
    transaction.schedule(); // 1
    if (!(client instanceof Binder)) {
        // If client is not an instance of Binder - it's a remote call and at this point it is
        // safe to recycle the object. All objects used for local calls will be recycled after
        // the transaction is executed on client in ActivityThread.
        transaction.recycle(); 
    }
}

在注释 1 处调用了 ClientTransaction.schedule 方法:

// /frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
private IApplicationThread mClient; 
public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this); // 1
}

注释 1 处的 mClientIApplicationThread 实例,在这里是 ApplicationThreadApplicationThreadActivityThread 的内部类,以下是相关源码:

// /frameworks/base/core/java/android/app/ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
    @Override
    public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        ActivityThread.this.scheduleTransaction(transaction); // 1
    }
}

注释 1 处调用了 ActivityThread.this.scheduleTransaction 方法,ActivityThread 继承自 ClientTransactionHandler,因此这里调用的是 ClientTransactionHandler.scheduleTransaction 方法,以下是相关源码:

// /frameworks/base/core/java/android/app/ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); // 1
}

注释 1 处的 ActivityThread.HHandler 的子类,以下是 ActivityThread.sendMessage 方法的源码和关于 ActivityThread.H.EXECUTE_TRANSACTION 的相关处理:

// /frameworks/base/core/java/android/app/ActivityThread.java
void sendMessage(int what, Object obj) {
    sendMessage(what, obj, 0, 0, false);
}

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
    if (DEBUG_MESSAGES) {
        Slog.v(TAG,
               "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
    }
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if (async) {
        msg.setAsynchronous(true);
    }
    mH.sendMessage(msg);
}

class H extends Handler {
    ...
    public static final int EXECUTE_TRANSACTION = 159;
	...
    public void handleMessage(Message msg) {
        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
        switch (msg.what) {
            ...
            case EXECUTE_TRANSACTION:
                final ClientTransaction transaction = (ClientTransaction) msg.obj;
                mTransactionExecutor.execute(transaction); // 1
                if (isSystem()) {
                    // Client transactions inside system process are recycled on the client side
                    // instead of ClientLifecycleManager to avoid being cleared before this
                    // message is handled.
                    transaction.recycle();
                }
                // TODO(lifecycler): Recycle locally scheduled transactions.
                break;
				...
        }
    }
}

在注释 1 处调用了 TransactionExecutor.execute 方法

// /frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void execute(ClientTransaction transaction) {
    ...
    executeCallbacks(transaction); // 1

    executeLifecycleState(transaction);
    mPendingActions.clear();
    if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}

@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
    ...
    final int size = callbacks.size();
    for (int i = 0; i < size; ++i) {
        final ClientTransactionItem item = callbacks.get(i);
        ...
        item.execute(mTransactionHandler, token, mPendingActions); // 2
        ..
    }
}

注释 2 处调用了 ClientTransactionItem.execute 方法,该方法在其子类 LaunchActivityItem 中实现,以下是 LaunchActivityItem.execute 方法:

// /frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java) 
@Override
public void execute(ClientTransactionHandler client, IBinder token,
                    PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
    ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                                                      mOverrideConfig, mCompatInfo, mReferrer, 
                                                      mVoiceInteractor, mState, 
                                                      mPersistentState,
                                                      mPendingResults, mPendingNewIntents, 
                                                      mIsForward,
                                                      mProfilerInfo, client, mAssistToken);
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */); // 1
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

注释 1 处的 clientClientTransactionHandler 的子类 ActivityThread,查看 ActivityThread.handleLauncherActivity 的源码,主要是调用了 ActivityThread.performLaunchActivity 方法:

// /frameworks/base/core/java/android/app/ActivityThread.java
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
                                     PendingTransactionActions pendingActions, 
                                     Intent customIntent) {
    ...
    WindowManagerGlobal.initialize();
    
	// 1 启动 Activity
    final Activity a = performLaunchActivity(r, customIntent);

    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        if (!r.activity.mFinished && pendingActions != null) {
            pendingActions.setOldState(r.state);
            pendingActions.setRestoreInstanceState(true);
            pendingActions.setCallOnPostCreate(true);
        }
    } else {
        // If there was an error, for any reason, tell the activity manager to stop us.
        try {
            // 停止 Activity 的启动
            ActivityTaskManager.getService()
                .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

    return a;
}

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ActivityInfo aInfo = r.activityInfo; // 2 获取 ActivityInfo 类
    if (r.packageInfo == null) {
        // 3 获取 APK 文件描述类 LoadApk
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                                       Context.CONTEXT_INCLUDE_CODE); 
    }

    ComponentName component = r.intent.getComponent(); // 4
    ...
    // 5 创建要启动的 Activity 的上下文环境
    ContextImpl appContext = createBaseContextForActivity(r); 
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        // 6 用类加载器创建该 Activity 的实例
        activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
        ...
    } catch (Exception e) {
        ...
    }

    try {
        // 7 创建 Application
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        ...
        if (activity != null) {
            ...
            // 8 初始化 Activity
            activity.attach(appContext, this, getInstrumentation(), r.token,
                            r.ident, app, r.intent, r.activityInfo, title, r.parent,
                            r.embeddedID, r.lastNonConfigurationInstances, config,
                            r.referrer, r.voiceInteractor, window, r.configCallback,
                            r.assistToken);
            ...
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); // 9
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            ...
        }
        ...
    } catch (SuperNotCalledException e) {
        throw e;

    } catch (Exception e) {
        ....
    }
    return activity;
}

注释 1 处调用了 ActivityThread.performLaunchActivity 方法来启动 Activity。注释 2 处用来获取 ActivityInfo,用来存储代码以及 AndroidManifest 设置的 ActivityReceiver 节点信息,比如,ActivitythemelaunchMode。在注释 3 处获取 APK 文件的描述类 LoadedApk。在注释 4 处获取要启动的 ActivityComponentName 类,在 ComponentName 类中保存了该 Activity 的包名和类名。在注释 5 处用来创建要启动的 Activity 的上下文环境。在注释 6 处根据 ComponentName 中存储的 Activity 类名,用类加载器来创建该 Activity 的实例 。注释 7 处用来创建 ApplicationLoadedApk.makeApplication 方法内部会调用 Application.onCreate 方法。注释 8 处调用 Activity.attach 方法初始化 Activity,在 Activity.attach 方法中会创建 Window 对象(PhoneWindow)并与 Activity 自身进行关联。在注释 9 处调用 Instrumentation.callActivityOnCreate 方法来启动 Activity

// /frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle,
                                 PersistableBundle persistentState) {
    prePerformCreate(activity);
    activity.performCreate(icicle, persistentState); // 1
    postPerformCreate(activity);
}

注释 1 处调用了 Activity.performCreate 方法,在 Activity.performCreate 方法中又调用了 Activity.onCreate 方法,到这里,根 Activity 就启动了,以下是相关源码:

// /frameworks/base/core/java/android/app/Activity.java
@UnsupportedAppUsage
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    dispatchActivityPreCreated(icicle);
    mCanEnterPictureInPicture = true;
    restoreHasCurrentPermissionRequest(icicle);
    // 1
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        onCreate(icicle);
    }
    writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
    mActivityTransitionState.readState(icicle);

    mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
        com.android.internal.R.styleable.Window_windowNoDisplay, false);
    mFragments.dispatchActivityCreated();
    mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
    dispatchActivityPostCreated(icicle);
}

@MainThread
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);

    if (mLastNonConfigurationInstances != null) {
        mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
    }
    if (mActivityInfo.parentActivityName != null) {
        if (mActionBar == null) {
            mEnableDefaultActionBarUp = true;
        } else {
            mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
        }
    }
    if (savedInstanceState != null) {
        mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
        mLastAutofillId = savedInstanceState.getInt(LAST_AUTOFILL_ID,
                                                    View.LAST_APP_AUTOFILL_ID);

        if (mAutoFillResetNeeded) {
            getAutofillManager().onCreate(savedInstanceState);
        }

        Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
        mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
                                   ? mLastNonConfigurationInstances.fragments : null);
    }
    mFragments.dispatchCreate();
    dispatchActivityCreated(savedInstanceState);
    if (mVoiceInteractor != null) {
        mVoiceInteractor.attachActivity(this);
    }
    mRestoredFromBundle = savedInstanceState != null;
    mCalled = true;

}

public void onCreate(@Nullable Bundle savedInstanceState,
                     @Nullable PersistableBundle persistentState) {
    onCreate(savedInstanceState);
}

参考

Android系统开机到Launcher启动流程分析文章来源地址https://www.toymoban.com/news/detail-427544.html

到了这里,关于Android系统启动(四) — Launcher 启动过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Framework 常见解决方案(24)屏蔽FallbackHome,去除 Android正在启动,直接进入Launcher

    开机以后,设备会有一个“android正在启动”这样的弹框,这个界面是一个叫FallbackHome的Activity来展示的。FallbackHome机制是Android系统启动过程中的一种降级处理机制。当系统启动时,如果默认的Launcher应用无法正常加载或出现错误,系统会自动启用FallbackHome来替代默认Launcher。

    2024年01月24日
    浏览(47)
  • Android 9.0 当系统内置两个Launcher时默认设置Launcher3以外的那个Launcher为默认Launcher

    在9.0系统rom定制化开发中,由于产品开发需要要求系统内置两个Launcher,一个是Launcher3,一个是自己开发的Launcher,当系统启动Launcher时, 不要弹出Launcher选择列表 选择哪个Launcher要求默认选择自己开发的Launcher作为默认Launcher,关于选择Launcher列表 其实都是在ResolverActivity.java中处理

    2024年01月18日
    浏览(44)
  • Android 10.0 当系统内置两个Launcher时默认设置Launcher3以外的那个Launcher为默认Launcher

    在10.0定制化开发中,由于产品开发需要要求系统内置两个Launcher,一个是Launcher3,一个是自己开发的Launcher,当系统启动Launcher时, 不要弹出Launcher选择列表 选择哪个Launcher要求默认选择自己开发的Launcher作为默认Launcher,关于选择Launcher列表 其实都是在ResolverActivity.java中处理的具

    2024年02月10日
    浏览(46)
  • Android 系统桌面 App —— Launcher 开发(1)

    Launcher就是Android系统的桌面,俗称“HomeScreen”也就是我们开机后看到的第一个App。launcher其实就是一个app,它的作用是显示和管理手机上其他App。目前市场上有很多第三方的launcher应用,比如“小米桌面”、“91桌面”等等 要让app作为Launcher,需要在Manifest中添加两个category:

    2024年02月11日
    浏览(61)
  • FrameWork的概述与启动过程

    Framework定义了客户端组件和服务端组件功能及接口。以下阐述中,“应用程序”一般是指“.apk”程序。 框架中包含三个主要部分,分别为服务端、客户端和Linux驱动。 服务端主要包含两个重要类,分别是WindowManagerService(WmS)和ActivityManagerService (AmS)。 WmS的作用是为所有的应

    2024年02月10日
    浏览(41)
  • Android启动过程 - Zygote

    在上一篇中,我们知道zygote进程是在`/system/etc/init/hw/init.rc`文件中配置,由init进程启动的。看下init中关于zygote的配置: 其中第一句import /system/etc/init/hw/init.${ro.zygote}.rc中的ro.zygote为属性,从源码看,对应的文件: core/rootdir/init.zygote64.rc、core/rootdir/init.zygote32.rc和init.zygote64_

    2024年02月22日
    浏览(35)
  • Android 应用启动过程优化

    应用启动流程: 1、startActivity 交给AMS判断处理(Binder通信) 2、AMS匹配到对应的应用信息后通知zygote去fork进程(socket通信) 3、反射调用ActivityThreadd的main函数之后,将匿名binder(ApplicationThread)交由AMS,建立了app的binder通信基础。 4、AMS通知App进程(binder通信)去创建启动Activity(on

    2024年02月07日
    浏览(40)
  • Android Activity启动过程详解

    1,《android系统启动流程简介》 2,《android init进程启动流程》 3,《android zygote进程启动流程》 4,《Android SystemServer进程启动流程》 5,《android launcher启动流程》 6,《Android Activity启动过程详解》 1,《Android 源码下载和编译》 2,《android 11源码编译和pixel3 刷机》 3,《Andro

    2024年02月09日
    浏览(49)
  • Android应用启动流程:从启动到可交互的过程解析

    关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。 我们继续总结学习 Android 基础知识 ,温故知新。 还是在多年前做系统应用开发的时候,通过编译源码学习了一

    2024年02月11日
    浏览(41)
  • 【干货】Android系统定制基础篇:第二部分(Launcher3支持键盘切换焦点、开发者模式密码确认、禁止非预装应用安装、配置时间)

    Android Launcher3 默认并不支持键盘操作,无法切换焦点,在一些需要支持键盘或遥控操作的设备中无法使用,因些对 Launcher3 做简单修改,使其支持键盘切换焦点。 在安全性要求比较高的产品中,一般会默认关闭『adb调试』,同时禁止用户打开『adb调试』功能。在Android8.1中默认

    2024年02月10日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包