Android 10.0 Launcher 启动流程

news2024/11/15 13:35:56

在前面SystemUI启动流程中说到,在SystemServer中会去启动各种系统服务,这里的launcher也是启动的其中一个服务ActivityManagerService去启动的。在android10之前,系统四大组件的启动都是在ActivityManagerService中,在android10中,单独抽出了一个ActivityTaskManagerService,主要负责Activity的管理和调度。这里先来看下ActivityManagerService服务的启动:
frameworks/base/services/java/com/android/server/SystemServer.java

private void startBootstrapServices() {
    ... ...
    // Activity manager runs the show.
    traceBeginAndSlog("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();
    traceEnd();
    ... ...
}

当SystemServiceManager调用 startService() 时,就会通过反射去创建传进去的class,然后在调用创建对象的 onStart() 方法,这里就是去初始化ActivityTaskManagerService和ActivityManagerService对象,并不会去启动launcher,而且系统服务启动分为三块:
frameworks/base/services/java/com/android/server/SystemServer.java

startBootstrapServices();   // 启动引导服务
startCoreServices();        // 启动核心服务
startOtherServices();       // 启动其他服务

在startOtherServices()中可以看到:
frameworks/base/services/java/com/android/server/SystemServer.java

private void startOtherServices() {
    ... ...
    // We now tell the activity manager it is okay to run third party
    // code.  It will call back into us once it has gotten to the state
    // where third party code can really run (but before it has actually
    // started launching the initial applications), for us to complete our
    // initialization.
    mActivityManagerService.systemReady(() -> {
        ... ...
    });
}

这就说明在所有服务初始化完成后,在这里会通知ActivityManagerService的systemReady()启动 launcher 的进程。
下面一起来看 launcher 是如何被启动起来的:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
    ... ...
    mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
    ... ...
    mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
    ... ...
}

mAtmInternal类型是ActivityTaskManagerInternal,这是一个抽象类,其实现是ActivityTaskManagerService的内部类LocalService:
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);
        }
    }
    ... ...
        @Override
    public void resumeTopActivities(boolean scheduleIdle){
        synchronized (mGlobalLock){
            mRootActivityContainer.resumeFocusedStacksTopActivities();
            if(scheduleIdle){
                mStackSupervisor.scheduleIdleLocked();
            }
        }
    }
    ... ...
}

这里的mRootActivityContainer类型是RootActivityContainer,按照文档上的说明,这是一个临时类,主要是将ActivityStackSupervisor.java中的一部分逻辑分离出来,在android11中,这个类就已经找不到了。替换成了RootWindowContainer,这里我们跟进 mRootActivityContainer.startHomeOnAllDisplays() 方法看,最终会调用到:startHomeOnDisplay() :
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

boolean startHomeOnDisplay(int userId,String reason,int displayId,boolean allowInstrumenting,boolean fromHomeKey){
    // Fallback to top focused display if the displayId is invalid.
    if(displayId==INVALID_DISPLAY){
        displayId=getTopDisplayFocusedStack().mDisplayId;
    }
 
    Intent homeIntent=null;
    ActivityInfo aInfo=null;
    if(displayId==DEFAULT_DISPLAY){
        //拿到需要启动launcher的intent,通过resolveHomeActivity解析出需要启动的Activity
        homeIntent=mService.getHomeIntent();
        aInfo=resolveHomeActivity(userId,homeIntent);
    }else if(shouldPlaceSecondaryHomeOnDisplay(displayId)){
        Pair<ActivityInfo, Intent> info=resolveSecondaryHomeActivity(userId,displayId);
        aInfo=info.first;
        homeIntent=info.second;
    }
    if(aInfo==null||homeIntent==null){
        return false;
    }
 
    if(!canStartHomeOnDisplay(aInfo,displayId,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);
    }
    // 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)+":"+displayId;
    mService.getActivityStartController().startHomeActivity(homeIntent,aInfo,myReason,
    displayId);
    return true;
}

这里可以分为两步看:
  1、通过ActivityTaskManagerService的getHomeIntent()获取到需要启动的intent,在通过resolveHomeActivity()解析出需要启动Activity的信息,
  2、mService.getActivityStartController()获取到的是ActivityStartController,这个类的主要作用是用于控制委派启动的Activity。
先来看下ActivityTaskManagerService的getHomeIntent() :
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);
        }
        return intent;
    }

注意看 intent.addCategory(Intent.CATEGORY_HOME) ,这个代表的就是要启动Activity的意图,通常来说,整个系统的只会有一个应用会在清单文件中配置CATEGORY_HOME,如果配置了多个,系统在启动的时候就会要求用户手动去选择哪个作为启动应用,如果在系统设置应用中进行配置了,就会选择配置的那个应用启动。(这个 CATEGORY_HOME 配置,说白了就只有 launcher 程序才会有)。
回到主线,接着看mService.getActivityStartController().startHomeActivity() :
frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java

    void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
            TaskDisplayArea taskDisplayArea) {
        final ActivityOptions options = ActivityOptions.makeBasic();
        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
        if (!ActivityRecord.isResolverActivity(aInfo.name)) {
            // The resolver activity shouldn't be put in home stack because when the foreground is
            // standard type activity, the resolver activity should be put on the top of current
            // foreground instead of bring home stack to front.
            options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
        }
        final int displayId = taskDisplayArea.getDisplayId();
        options.setLaunchDisplayId(displayId);
        options.setLaunchTaskDisplayArea(taskDisplayArea.mRemoteToken
                .toWindowContainerToken());
        // The home activity will be started later, defer resuming to avoid unneccerary operations
        // (e.g. start home recursively) when creating home stack.
        mSupervisor.beginDeferResume();
        final ActivityStack homeStack;
        try {
            // Make sure home stack exists on display area.
            homeStack = taskDisplayArea.getOrCreateRootHomeTask(ON_TOP);
        } finally {
            mSupervisor.endDeferResume();
        }
        mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
                .setOutActivity(tmpOutRecord)
                .setCallingUid(0)
                .setActivityInfo(aInfo)
                .setActivityOptions(options.toBundle())
                .execute();
        mLastHomeActivityStartRecord = tmpOutRecord[0];
        if (homeStack.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();
        }
    }
    /**
     * @return A starter to configure and execute starting an activity. It is valid until after
     *         {@link ActivityStarter#execute} is invoked. At that point, the starter should be
     *         considered invalid and no longer modified or used.
     */
    ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }

这里主要是先获取一个ActivityStarter(主要用于启动Activity),然后把需要的参数设置进去,最后再调用它的ActivityStarter.execute()方法:
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

int execute() {
    try {
        ... ...
        final LaunchingState launchingState;
        synchronized (mService.mGlobalLock) {
            final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
            // 通过ActivityMetricsLogger.notifyActivityLaunching创建LaunchingState并记录创建Activity开始的时间
            launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
                    mRequest.intent, caller);
        }
        
        ... ...
        // 执行启动请求
        res = executeRequest(mRequest);
        ... ...
        
        // Notify ActivityMetricsLogger that the activity has launched.
        // ActivityMetricsLogger will then wait for the windows to be drawn and populate
        // WaitResult.
        // 通过ActivityMetricsLogger.notifyActivityLaunched记录Activity启动完成的时间
        mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
                mLastStartActivityRecord);
        // 同时将Request.waitResult添加到ActivityStackSupervisor的mWaitingActivityLaunched中,等待窗口绘制完成
        return getExternalResult(mRequest.waitResult == null ? res
                : waitForResult(res, mLastStartActivityRecord));        
        } finally {
            onExecutionComplete();
        }
    }

通过上面代码我们知道,启动是在 executeRequest() 方法里:
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

    private int executeRequest(Request request) {
    ... ...
        //调用 startActivityUnchecked
        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
                restrictedBgActivity, intentGrants);
        return mLastStartActivityResult;
    }

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, Task inTask,
                boolean restrictedBgActivity, NeededUriGrants intentGrants) {
        int result = START_CANCELED;
      ... ...
        try {
            //延时布局
            mService.deferWindowLayout();
            //执行startActivityInner
            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
        } finally {
            //恢复布局
            mService.continueWindowLayout();
        }
      ... ...
        return result;
    }

ActivityStarter.startActivityInner()
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

int startActivityInner() { 
    ... ...
       if (mDoResume) {
            //ActivityRecord 记录着 Activity 信息
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isTopActivityFocusable()
                    || (topTaskActivity != null && topTaskActivity.isTaskOverlay()
                    && mStartActivity != topTaskActivity)) {
                mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
            } else {
                //执行resumeFocusedStacksTopActivities
                mRootWindowContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);
            }
        }
    ... ...
        return START_SUCCESS;
    }

RootWindowContainer.resumeFocusedStacksTopActivities()
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

boolean resumeFocusedStacksTopActivities(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    ... ...
        //如果是栈顶Activity,启动resumeTopActivityUncheckedLocked
        if (targetStack != null && (targetStack.isTopStackInDisplayArea()
                || getTopDisplayFocusedStack() == targetStack)) {
            result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
    ... ...
        if (!resumedOnDisplay) {
            //获取栈顶的 ActivityRecord
            final ActivityStack focusedStack = display.getFocusedStack();
            if (focusedStack != null) {
                //执行resumeTopActivityUncheckedLocked
                result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
            }else if (targetStack == null) {
                    result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
                            display.getDefaultTaskDisplayArea());
            }
        }
      return result;
}

ActivityStack.resumeTopActivityUncheckedLocked()
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java

    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mInResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }
        boolean result = false;
        try {
            mInResumeTopActivity = true;
            // 执行 resumeTopActivityInnerLocked,
            // 最终调用到 ActivityStackSupervisor.startSpecificActivity()
            result = resumeTopActivityInnerLocked(prev, options);
            final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
            if (next == null || !next.canTurnScreenOn()) {
                checkReadyForSleep();
            }
        } finally {
            mInResumeTopActivity = false;
        }
        return result;
    }

ActivityStackSupervisor.startSpecificActivity()
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java

    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;
        }
 
        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
 
        final boolean isTop = andResume && r.isTopRunningActivity();
        //进程不存在 mService =ATMS
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }

startSpecificActivity() 这个方法是关键方法,如果进程已经存在直接执行 realStartActivityLocked 去启动 Activity,进程不存在则通过AMS去创建 Socket,然后通知 Zygote 去 fork 进程。由于这里第一次创建,所以会走到 startProcessAsync() 。
Launcher启动流程调用栈:

创建Socket建立连接
ActivityTaskManagerService.startProcessAsync()
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

    void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
            String hostingType) {
        try {
            if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:"
                        + activity.processName);
            }
            // Post message to start process to avoid possible deadlock of calling into AMS with the
            // ATMS lock held.
            final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
                    mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
                    isTop, hostingType, activity.intent.getComponent());
            mH.sendMessage(m);
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
    }

通过handler发消息执行ActivityManagerInternal.startProcess() ,内部又转调用ActivityManagerService.startProcessLocked() :
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

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

mProcessList类型是ProcessList,这是一个进程管理类,描述了进程的adj值,当系统资源吃紧时,就会根据这里描述的adj去判断杀死哪个应用来释放资源,可以通过adb shell dumpsys meminfo来查看当前所有进程的分类情况,接着来看下ProcessList.startProcessLocked():
frameworks/base/services/core/java/com/android/server/am/ProcessList.java

    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) {
        
        ProcessRecord app;
        ... ...
        checkSlow(startTime, "startProcess: stepping in to startProcess");
        final boolean success = startProcessLocked(app, hostingRecord, abiOverride);
        checkSlow(startTime, "startProcess: done starting proc!");
        return success ? app : null;
    }
 
    boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            boolean disableHiddenApiChecks, boolean mountExtStorageFull,
            String abiOverride) {
            ... ...
        try {
            ... ...
            // Start the process.  It will either succeed and return a result containing
            // the PID of the new process, or else throw a RuntimeException.
            final String entryPoint = "android.app.ActivityThread";
 
            return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
                    startTime);
        } catch (RuntimeException e) {
            Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
 
            // Something went very wrong while trying to start this process; one
            // common case is when the package is frozen due to an active
            // upgrade. To recover, clean up any active bookkeeping related to
            // starting this process. (We already invoked this method once when
            // the package was initially frozen through KILL_APPLICATION_MSG, so
            // it doesn't hurt to use it again.)
            mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                    false, false, true, false, false, app.userId, "start failure");
            return false;
        }
    }
 
    boolean startProcessLocked(HostingRecord hostingRecord,String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,long startTime) {
            ... ...
            final Process.ProcessStartResult startResult = startProcess(app.hostingRecord,entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
            ... ...
    }
 
    private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
        try {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            checkSlow(startTime, "startProcess: asking zygote to start proc");
            final Process.ProcessStartResult startResult;
            if (hostingRecord.usesWebviewZygote()) {
                ... ...
            } else if (hostingRecord.usesAppZygote()) {
                final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
 
                startResult = appZygote.getProcess().start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        /*useUsapPool=*/ false,
                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
            } else {
                ... ...
            }
            checkSlow(startTime, "startProcess: returned from zygote!");
            return startResult;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

这里有几个我们需要关注的点,一个是第二个方法定义的entryPoint=“android.app.ActivityThread”,这个就是后面创建进程时会通过反射调用到的类,再来看最后一个方法,这里会执行else if语句,也就是执行ZygoteProcess的start()方法。最终到 ZygoteProcess 的attemptUsapSendArgsAndGetResult 通过 Socket 通信,fork 一个新的 Launcher 进程,调用过程如图:

ZygoteProcess.attemptZygoteSendArgsAndGetResult()
frameworks/base/core/java/android/os/ZygoteProcess.java

    private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
            ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
        try {
            final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
            final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;
 
            zygoteWriter.write(msgStr);把应用进程的一些参数写给前面连接的zygote进程
            zygoteWriter.flush();//进入Zygote进程,处于阻塞状态
            //从socket中得到zygote创建的应用pid,赋值给 ProcessStartResult的对象
            Process.ProcessStartResult result = new Process.ProcessStartResult();
            result.pid = zygoteInputStream.readInt();
            result.usingWrapper = zygoteInputStream.readBoolean();
            return result;
        } catch (IOException ex) {
            zygoteState.close();
        }
    }

Zygote进程处理
ZygoteInit.main
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static void main(String argv[]) {
    Runnable caller;
    if (startSystemServer) {
        //Zygote Fork出的第一个进程 SystmeServer
        Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
 
        if (r != null) {
            r.run();
            return;
        }
    }
    //循环等待fork出其他的应用进程,比如Launcher
    caller = zygoteServer.runSelectLoop(abiList);
    ...
    if (caller != null) {
        caller.run(); //执行runSelectLoop返回的Runnable对象,进入子进程
    }
}

ZygoteServer.runSelectLoop
frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

Runnable runSelectLoop(String abiList) {
    while (true) {
        int pollReturnValue;
            try {
                //epoll机制 循环
                pollReturnValue = Os.poll(pollFDs, pollTimeoutMs);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }
            ...
            //来了消息后,调用processOneCommand()来进行进程的处理
            final Runnable command =  connection.processOneCommand(this);
    } 
}

ZygoteConnection.processOneCommand
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

Runnable processOneCommand(ZygoteServer zygoteServer) {
            //fork进程,得到新进程pid
            //pid=0 表示Zygote  fork子进程成功
            //pid > 0 表示子进程 的真正的PID
            pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
                parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
                parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
                parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
        try {
            //fork成功,第一次返回的pid = 0
            if (pid == 0) {
                return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
            } else {
                handleParentProc(pid, serverPipeFd);
                return null;
            }
}

ZygoteConnection.handleChildProc
这里主要执行到 ZygoteInit.zygoteInit,zygoteInit 进行一些环境的初始化、启动Binder进程等操作,最终反射执行 ActivityThread.main
frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

    private Runnable handleChildProc(ZygoteArguments parsedArgs,
            FileDescriptor pipeFd, boolean isZygote) {
        closeSocket();
        Zygote.setAppProcessName(parsedArgs, TAG);
            if (!isZygote) {
                //App进程将会调用到这里,最终反射执行ActivityThread.main
                return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                        parsedArgs.mDisabledCompatChanges,
                        parsedArgs.mRemainingArgs, null /* classLoader */);
            } else {
                return ZygoteInit.childZygoteInit(parsedArgs.mTargetSdkVersion,
                        parsedArgs.mRemainingArgs, null /* classLoader */);
            }
        
    }

Zygote进程调用栈:

ActivityThread中处理
Zygote fork出了 Launcher 的进程,并把接下来的 Launcher 启动任务交给了 ActivityThread 来进行,接下来我们就从 ActivityThread.main方法来分析 Launcher 的创建过程。
frameworks/base/core/java/android/app/ActivityThread.java

    public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        ... ...
        //创建主线程Looper
        Looper.prepareMainLooper();
        ... ...
        ActivityThread thread = new ActivityThread();
        //执行attach
        ... ...
        thread.attach(false, startSeq);
        //开启循环
        ... ...
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

这里就是android层面划分为一个应用进程的开始,初始化一个looper,也就是android中说的主线程,并开始looper循环,这里调用到了ActivitThread.attach() :
frameworks/base/core/java/android/app/ActivityThread.java

    private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
            ... ...
            // 这里会拿到ActivityManagerService的代理
            final IActivityManager mgr = ActivityManager.getService();
            try {
               //应用的句柄发给AMS,从而使AMS可以管理新进程
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
             ... ...
        } else {
            // 在前面讲Zygote进程的时候,里面创建ActivityThread就会执行到这里
        }
 
        //当系统配置发生变更时会执行这个回调
        ViewRootImpl.ConfigChangedCallback configChangedCallback
                = (Configuration globalConfig) -> {
            ... ...
        };
        ViewRootImpl.addConfigCallback(configChangedCallback);
    }

这里会执行if语句里面的内容,mAppThread的类型是ApplicationThread,这个类的主要作用是在ActivityManagerService中回调回ActivityThread中来,mgr是ActivityManagerService的代理,在执行它的ActivityManagerService.attachApplication() 方法:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    public final void attachApplication(IApplicationThread thread, long startSeq) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }

ActivityManagerService.attachApplicationLocked()
调用AMS的 attachApplication(),最终层层调用到 ActivityStackSupervisor 的 realStartActivityLocked,真正准备去启动Activity。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    private final boolean attachApplicationLocked(IApplicationThread thread,int pid, int callingUid, long startSeq) {
        ... ...
        //这里会去调用ActivityThrea的bindApplication(),也就是会去创建Application
        thread.bindApplication(... ...)
        ... ...
        //如果当前的Application记录仍然依附到之前的进程中,则清理掉
        if (app.thread != null) {
            handleAppDiedLocked(app, true, true);
        }
        ... ...
        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                //调用ActivityTaskManagerService的attachApplication(),最终层层调用到ActivityStackSupervisor.java的 realStartActivityLocked()
                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
        ... ...
    }

这里通过AMS最终会调用到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 {
        //确保所有的Activity执行了onPause才会往下继续执行
        if (!mRootActivityContainer.allPausedActivitiesComplete()) {
            // While there are activities pausing we skipping starting any new activities until
            // pauses are complete. NOTE: that we also do this for activities that are starting in
            // the paused state because they will first be resumed then paused on the client side.
            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                    "realStartActivityLocked: Skipping start of r=" + r
                    + " some activities pausing...");
            return false;
        }
        ... ...
 
        try {
            ... ...
            try{
                ... ...
                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);
 
                final DisplayContent dc = r.getDisplay().mDisplayContent;
                //在回调序列的末尾添加一条消息
                clientTransaction.addCallback(LaunchActivityItem.obtain(... ...));
 
                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                //添加最后执行的生命周期状态
                clientTransaction.setLifecycleStateRequest(lifecycleItem);
 
                // 这里其实就是执行ClientTransaction的schedule()方法
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
                ... ...
            } catch (RemoteException e) {
                if (r.launchFailed) {
                    // 第二次启动失败,finish activity并放弃启动
                    Slog.e(TAG, "Second failure launching "
                            + r.intent.getComponent().flattenToShortString() + ", giving up", e);
                    proc.appDied();
                    stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                            "2nd-crash", false);
                    return false;
                }
 
                //第一次启动失败,尝试重启进程
                r.launchFailed = true;
                proc.removeActivity(r);
                throw e;
            }
        } finally {
            endDeferResume();
        }
        ... ...
 
        return true;
    }

ActivityThread调用栈:

小结

至此已经走到 realStartActivityLocked,接下来就是 Activity 的启动流程,Activity 启动下篇文章会单独分析。总结一下 Launcher 启动流程,Launcher的启动经过了三个阶段:
  1、SystemServer 创建AMS和ATMS,通过 SystemReady 进入 LauncherActivity 的调用
  2、Zygote 进程 fork 出 Launcher 进程,通过 Socket 进行通信
  3、进入 ActivityThread 的处理,完成 Launcher 的 Acitivty 启动

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1967381.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NPDP学习之路:科学规划顺利拿证

备考策略&#xff1a;制定合理学习计划 开始学习前需要制定一个合理的学习计划是备考过程中的关键。 最好根据自己个人的工作和生活习惯&#xff0c;合理安排每天的学习时间&#xff0c;并合理分配各个知识点的学习进度&#xff0c;把不理解的问题提前记录下来&#xff0c;要…

[渗透测试学习] Editorial-HackTheBox

文章目录 Editorial-HackTheBox信息搜集漏洞利用权限提升参考文章Editorial-HackTheBox 信息搜集 nmap扫描端口 nmap -sV -sC -v 10.10.11.20扫描结果如下 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.7 (Ubuntu Linux; protocol 2.…

报销管理软件怎么选?主流的10款对比

国内外排名前十的报销软件大对比&#xff1a;合思、Zoho Expense、金蝶财务报销系统、每刻报销、慧算账、Expensify、齐业成、汇联易、分贝通、QuickBooks Online。 在小型企业中&#xff0c;报销管理可能还可以由财务人员手工完成。然而&#xff0c;对于中到大型企业和快速发展…

『 Linux 』基于阻塞队列的生产者消费者模型

文章目录 生产者-消费者模型概述生产者消费者模型的高效性虚假唤醒信号丢失生产者消费者模型的模拟实现参考代码 生产者-消费者模型概述 生产者消费者模型是一种多线程设计模式,常见于解决多个生产者线程和多个消费者线程之间如何安全有效地共享数据; 该模型中存在三种关系,两个…

多级指针的使用

文章目录 &#x1f34a;自我介绍&#x1f34a;指针的设计规则&#x1f34a;多级指针的结论&#x1f34a;二级指针输出数组中的某个值的表示方法 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&#xff08;一键四连&#xff09;哦~ &…

Effective Java 中文版(第2版 电子版教程)

前言 Java从诞生到日趋完善&#xff0c;经过了不断的发展壮大&#xff0c;目前全世界拥有了成千上万的Java开发人员。如何编写出更清晰、更正确、更健壮且更易于重用的代码&#xff0c;是大家所追求的目标之一。本书的作者JoshuaBloch曾经是Sun公司的杰出工程师&#xff0c;带…

vite+typescript项目 报错:找不到模块“./*.vue”或其相应的类型声明——解决方案

declare module *.vue {import type { DefineComponent } from vueconst vueComponent: DefineComponent<{}, {}, any>export default vueComponent }

fastjson-1.2.24利用

参考视频&#xff1a;fastjson反序列化漏洞2-1.2.24利用 参考博客&#xff1a;Fastjson系列二——1.2.22-1.2.24反序列化漏洞 分析版本 fastjson1.2.24 JDK 8u141 fastjson反序列化特点 不需要实现Serializable 因为对于找不到符合条件的反序列化器&#xff0c;就把类当作…

SAP ERP 通过SAP PO LDAP适配器与微软AD域服务系统集成案例

一、客户介绍 上海某芯片制造公司的主要产品应用于图像传感器、 图像信号处理芯片、 低功耗芯片、 射频芯片等。专注集成电路技术开发与制造&#xff0c;服务于图像传感器、图形图像信号处理芯片、低功耗芯片、射频芯片等领域的全球客户。 二、项目需求 该企业内部办公电…

Flutter 初识:数据表格和卡片

Flutter数据表格和卡片小结 Table属性解析示例TableRow属性解析 TableCell属性解析 DataTable属性解析示例DataColumn属性解析示例 DataRow属性解析示例 DataCell属性解析 Card属性解析示例 Table Table 是 Flutter 中用于显示表格布局的小部件。它允许你定义行和列&#xff0…

前端日历插件VCalendar

官网地址 API | VCalendar 1.安装 yarn add v-calendarnext popperjs/core 2.全局引入 mian.js //日历插件 import VCalendar from v-calendar; import v-calendar/style.css;app.use(VCalendar); 3.使用 <div><VCalendar reservationTime expanded borderless…

无涯问知AI PC版发布,星环科技开启个人大模型应用新篇章

5月30-31日&#xff0c;2024向星力未来数据技术峰会期间&#xff0c;星环科技推出无涯问知AI PC版&#xff0c;这是一款专为个人用户设计的大模型应用产品&#xff0c;标志着个人智能应用时代的全面展开。 无涯问知AI PC版基于星环科技先进的大模型技术&#xff0c;可以在配备英…

jenkins获取sonarqube质量门禁结果

前景 在使用 Jenkins 集成 SonarQube 时&#xff0c;获取质量门禁&#xff08;Quality Gate&#xff09;结果非常重要。SonarQube 的质量门禁是一种质量控制机制&#xff0c;用于评估代码质量是否符合预设的标准。以下是获取质量门禁结果的意义和作用&#xff1a; 评估代码质量…

跟张良均老师学大数据人工智能-批量集训营开班中

随着我国大数据和人工智能产业的飞速发展&#xff0c;未来社会对高素质科技人才的需求日益旺盛。为助力广大青少年提前掌握前沿技术&#xff0c;实现自我价值&#xff0c;泰迪智能科技多名优秀老师联合打造暑期大数据人工智能集训营&#xff0c;旨在培养具备创新精神和实战能力…

常见红外协议整理

1.NEC 1.1 信号编码 载波频率&#xff1a;38kHz载波&#xff0c;载波占空比建议位1/3或1/4。 逻辑"0":562.5μs的脉冲burst(约21个周期) 562.5μs的空闲,总时长1.125ms 逻辑"1":562.5μs的脉冲burst(约21个周期) 1.6875ms的空闲,总时长2.25ms 引导…

大模型的一些思考

迄今为止&#xff0c;应该没有人还怀疑大模型的能力吧&#xff1f;但目前大模型实现真正落地&#xff0c;其实还有一段艰难的路要走。 和大模型相关的一些术语 **1. 大模型&#xff1a;**一般指1亿以上参数的模型&#xff0c;但是这个标准一直在升级&#xff0c;目前万亿参数…

树模型详解3-xgboost

回归树&#xff1a; 表达式为T&#xff08;x&#xff09;wq&#xff08;x&#xff09;&#xff0c;意思为&#xff1a;一个样本x&#xff0c;落到树的哪个叶子结点由q&#xff08;x&#xff09;得出&#xff0c;具体叶子结点对应的值由w函数得出 如何构建函数&#xff1a; 运…

智能视频监控在车辆管理与安全预警中的应用挑战

随着公共交通的客货运事业蓬勃发展&#xff0c;车辆保有量逐年增加&#xff0c;交通安全管理形势愈发严峻。为应对超速、疲劳驾驶、两客一危等违规驾驶行为&#xff0c;智能视频监控技术成为提升交通安全管理水平的关键手段。然而&#xff0c;尽管智能视频监控技术在理论上具有…

MATLAB(9)GIS模型

一、介绍 在GIS&#xff08;地理信息系统&#xff09;中&#xff0c;模型的实现可以非常多样化&#xff0c;取决于你想要解决的具体问题。MATLAB作为一个强大的数值计算和可视化工具&#xff0c;可以被用来开发GIS相关的模型&#xff0c;尽管它不是专门为GIS设计的&#xff08…

免费【2024】springboot 大学生二手电子产品交易平台设计与实现

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…