从Launcher启动一个APP流程 Android 12

一、概要

  1. Launcher向AMS请求startActivity,启动目标APP应用界面
  2. AMS检查当前APP进程是否启动,进程没有启动时,执行AMS中的 startProcessLocked函数,向zygote请求新建应用进程。
  3. 新建应用进程后,应用进程中执行ActivityThread中的main函数。main函数执行attachApplication,向AMS进行绑定。
  4. AMS收到attachApplication消息后,调用IApplicationThread.aidl接口的bindApplicationscheduleTransactionbindApplication通知应用进程创建Application,scheduleTransaction通知应用进程启动第一个Activity界面。
  5. scheduleTransaction会启动第一个Activity。创建Activity,PhoneWindow, DecorView对象,会执行Activity的onCreate、onStart、onResume回调函数,还会通过WindowManagerViewRootImpl将Activity窗口绘制出来。

二、启动新进程

在这里插入图片描述

1. Launcher调用startActivity

  • Instrumentation对象封装了startActivity功能
android/app/Instrumentation.java

    public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, String target,
        Intent intent, int requestCode, Bundle options) {
    
    
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        // 省略代码...
        try {
    
    
            intent.migrateExtraStreamToClipData(who);
            intent.prepareToLeaveProcess(who);
            int result = ActivityTaskManager.getService().startActivity(whoThread,
                    who.getOpPackageName(), who.getAttributionTag(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()), token, target,
                    requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
    
    
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

2. AMS启动新进程

2.1 ActivityTaskManagerService 处理startActivity请求

  • ActivityStarter 负责启动Activity。
  • ActivityTaskSupervisor 会进行一系列复杂的逻辑、状态判断,包括task的创建。
com/android/server/wm/ActivityTaskManagerService.java
    private int startActivityAsUser(IApplicationThread caller, String callingPackage,
            @Nullable String callingFeatureId, Intent intent, String resolvedType,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
    
    
        assertPackageMatchesCallingUid(callingPackage);
        enforceNotIsolatedCaller("startActivityAsUser");

        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setCallingFeatureId(callingFeatureId)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setUserId(userId)
                .execute();

    }

2.2 通知AMS启动新进程

  • 先判断Process是否存在,存在则直接启动Activity,否则调用startProcessAsync,先启动进程。
com/android/server/wm/ActivityTaskSupervisor.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()) {
    
     // 进程存在,并且IApplicationThread对象不为空时,直接启动Activity
            try {
    
    
                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();
        // 通知AMS启动新进程,此处MService对象是ATMS
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }
  • AMS 执行startProcess
com/android/server/am/ActivityManagerService.java
    final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
            boolean isolated) {
    
    
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
                null /* ABI override */, null /* entryPoint */,
                null /* entryPointArgs */, null /* crashHandler */);
    }
  • ProcessList执行startProcess
com/android/server/am/ProcessList.java
    private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
            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;
            boolean regularZygote = false;
            if (hostingRecord.usesWebviewZygote()) {
    
    
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        app.getDisabledCompatChanges(),
                        new String[]{
    
    PROC_START_SEQ_IDENT + app.getStartSeq()});
            } else if (hostingRecord.usesAppZygote()) {
    
    
                final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);

                // We can't isolate app data and storage data as parent zygote already did that.
                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,
                        /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
                        app.getDisabledCompatChanges(), pkgDataInfoMap, allowlistedAppDataInfoMap,
                        false, false,
                        new String[]{
    
    PROC_START_SEQ_IDENT + app.getStartSeq()});
            } else {
    
    
                regularZygote = true;
                // 默认的进程启动方式
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
                        isTopApp, app.getDisabledCompatChanges(), pkgDataInfoMap,
                        allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
                        new String[]{
    
    PROC_START_SEQ_IDENT + app.getStartSeq()});
            }
            checkSlow(startTime, "startProcess: returned from zygote!");
            return startResult;
        } finally {
    
    
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
    }

3. Zygote 启动新进程

3.1 fork新进程

  • 通过socket进行通信,通知启动新进程。
  • 最终是调用Linux fork函数复制新进程。
com/android/internal/os/Zygote.java
    static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
            int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
            int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
            boolean isTopApp, String[] pkgDataInfoList, String[] allowlistedDataInfoList,
            boolean bindMountAppDataDirs, boolean bindMountAppStorageDirs) {
    
    
        ZygoteHooks.preFork();

        int pid = nativeForkAndSpecialize(
                uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
                fdsToIgnore, startChildZygote, instructionSet, appDataDir, isTopApp,
                pkgDataInfoList, allowlistedDataInfoList, bindMountAppDataDirs,
                bindMountAppStorageDirs);
        if (pid == 0) {
    
    
            // Note that this event ends at the end of handleChildProc,
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");

            // If no GIDs were specified, don't make any permissions changes based on groups.
            if (gids != null && gids.length > 0) {
    
    
                NetworkUtilsInternal.setAllowNetworkingForProcess(containsInetGid(gids));
            }
        }

        // Set the Java Language thread priority to the default value for new apps.
        Thread.currentThread().setPriority(Thread.NORM_PRIORITY);

        ZygoteHooks.postForkCommon();
        return pid;
    }

3.2 执行新进程的main函数

  • 反射调用ActivityThread的main函数。入参的className默认是ActivityThread类名称。
com/android/internal/os/RuntimeInit.java
    protected static Runnable findStaticMain(String className, String[] argv,
            ClassLoader classLoader) {
    
    
        Class<?> cl;

        try {
    
    
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
    
    
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
    
    
            m = cl.getMethod("main", new Class[] {
    
     String[].class }); // main函数
        } catch (NoSuchMethodException ex) {
    
    
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
    
    
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
    
    
            throw new RuntimeException(
                    "Main method is not public and static on " + className);
        }

        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
        return new MethodAndArgsCaller(m, argv);
    }

三、Application绑定与Acitivity创建

在这里插入图片描述

1. APP的main 函数

  • 创建主线程Looper对象
android/app/ActivityThread.java

    public static void main(String[] args) {
    
    
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        // 省略...
        Looper.prepareMainLooper();
        // 省略...
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq); // 调用AMS的attachApplication

        if (sMainThreadHandler == null) {
    
    
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
    
    
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

2. attach 函数

  • 调用AMS的attachApplication,这个函数是同步的。
android/app/ActivityThread.java
    private void attach(boolean system, long startSeq) {
    
    
        sCurrentActivityThread = this;
        mConfigurationController = new ConfigurationController(this);
        mSystemThread = system;
        if (!system) {
    
    
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
    
    
                mgr.attachApplication(mAppThread, startSeq); // 调用AMS的attachApplication函数
            } catch (RemoteException ex) {
    
    
                throw ex.rethrowFromSystemServer();
            }
            // 省略...
        } else {
    
    
            // Don't set application object here -- if the system crashes,
            // we can't display an alert, we just want to die die die.
            android.ddm.DdmHandleAppName.setAppName("system_process",
                    UserHandle.myUserId());
            try {
    
    
                mInstrumentation = new Instrumentation();
                mInstrumentation.basicInit(this);
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                mInitialApplication.onCreate();
            } catch (Exception e) {
    
    
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
        }
        // 省略...
    }

3. AMS 的 attachApplication 函数

  • 调用了IApplicationThread.aidlbindApplicationscheduleTransaction函数,这两个函数是异步的。

3.1 通过IApplicationThread.aidl调用APP进程的 bindApplication 函数

com/android/server/am/ActivityManagerService.java
    @GuardedBy("this")
    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
    
    

        // Find the application record that is being attached...  either via
        // the pid if we are running in multiple processes, or just pull the
        // next app record if we are emulating process with anonymous threads.
        ProcessRecord app;
        long startTime = SystemClock.uptimeMillis();
        long bindApplicationTimeMillis;
        if (pid != MY_PID && pid >= 0) {
    
    
            synchronized (mPidsSelfLocked) {
    
    
                app = mPidsSelfLocked.get(pid); // 获取ProcessRecord对象
            }
            // 省略异常校验代码...
        } else {
    
    
            app = null;
        }
        // 省略异常校验代码...

        final String processName = app.processName;
        try {
    
    
            AppDeathRecipient adr = new AppDeathRecipient(
                    app, pid, thread);
            thread.asBinder().linkToDeath(adr, 0); // binder died 异常回调绑定
            app.setDeathRecipient(adr);
        } catch (RemoteException e) {
    
    
            app.resetPackageList(mProcessStats);
            mProcessList.startProcessLocked(app,
                    new HostingRecord("link fail", processName),
                    ZYGOTE_POLICY_FLAG_EMPTY);
            return false;
        }
        // 省略代码....
        try {
    
    
            // 省略代码....
            checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
            bindApplicationTimeMillis = SystemClock.elapsedRealtime();
            mAtmInternal.preBindApplication(app.getWindowProcessController());
            final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
            if (mPlatformCompat != null) {
    
    
                mPlatformCompat.resetReporting(app.info);
            }
            final ProviderInfoList providerList = ProviderInfoList.fromList(providers);
            if (app.getIsolatedEntryPoint() != null) {
    
    
                // This is an isolated process which should just call an entry point instead of
                // being bound to an application.
                thread.runIsolatedEntryPoint(
                        app.getIsolatedEntryPoint(), app.getIsolatedEntryPointArgs());
            } else if (instr2 != null) {
    
    
                // APP自定义ActiveInstrumentation对象时,一般用于开发人员测试场景,启动流程
                thread.bindApplication(processName, appInfo, providerList,
                        instr2.mClass,
                        profilerInfo, instr2.mArguments,
                        instr2.mWatcher,
                        instr2.mUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.getCompat(), getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.getDisabledCompatChanges(), serializedSystemFontMap);
            } else {
    
    
                // 默认情况下的流程
                thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.getCompat(), getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.getDisabledCompatChanges(), serializedSystemFontMap);
            }
            // 省略代码...
        } catch (Exception e) {
    
    
            // 省略异常流程...
            return false;
        }
        // 省略启动Activity 或者 Service 流程...
        return true;
    }

3.2 通知应用进程启动Activity

  1. AMS中调用ActivityTaskManagerServiceattachApplication函数
  2. 调用RootWindowContainerattachApplication函数
  3. 最终,调用ActivityTaskSupervisorrealStartActivityLocked函数,执行scheduleTransaction流程
  • AMS中的application函数流程
com/android/server/am/ActivityManagerService.java
    @GuardedBy("this")
    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
    
    
        // 省略bindApplication流程...

        boolean badApp = false;
        boolean didSomething = false;

        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
    
     // 如果是正常启动流程
            try {
    
    
                // 最终调用到ActivityTaskSupervisor的realStartActivityLocked函数
                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
            } catch (Exception e) {
    
    
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }

        // Find any services that should be running in this process...
        if (!badApp) {
    
    
            try {
    
    
                // 启动Service流程
                didSomething |= mServices.attachApplicationLocked(app, processName);
                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
            } catch (Exception e) {
    
    
                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                badApp = true;
            }
        }
        // 省略流程...

        if (!didSomething) {
    
    
            updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_PROCESS_BEGIN); // 更新进程优先级
            checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
        }
        // 省略代码...
        return true;
    }
  • ActivityTaskSupervisorrealStartActivityLocked函数,执行scheduleTransaction流程
    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {
    
    
         // 省略代码...
        try {
    
    
             // 省略代码...
            try {
    
    
                 // 省略准备参数的代码...

                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);

                final boolean isTransitionForward = r.isTransitionForward();
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
                        proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
                        results, newIntents, r.takeOptions(), isTransitionForward,
                        proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
                        r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,
                        r.getLaunchedFromBubble()));

                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
    
    
                    lifecycleItem = ResumeActivityItem.obtain(isTransitionForward); // ActivityResume状态
                } else {
    
    
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem); // 设置生命周期对象

                // Schedule transaction. 真正transaction流程,启动Activity
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
                 // 省略代码...
            } catch (RemoteException e) {
    
    
                if (r.launchFailed) {
    
    
                    // This is the second time we failed -- finish activity and give up.
                    Slog.e(TAG, "Second failure launching "
                            + r.intent.getComponent().flattenToShortString() + ", giving up", e);
                    proc.appDied("2nd-crash");
                    r.finishIfPossible("2nd-crash", false /* oomAdj */);
                    return false;
                }

                // This is the first time we failed -- restart process and
                // retry.
                r.launchFailed = true;
                proc.removeActivity(r, true /* keepAssociation */);
                throw e;
            }
        } finally {
    
    
            endDeferResume();
            proc.resumeConfigurationDispatch();
        }
        // 省略代码...
        return true;
    }

四、Activity 在onResume函数流程

  1. 创建Activity,PhoneWindow, DecorView对象
  2. 执行Activity的onCreate、onStart、onResume回调函数
  3. addWindow。向WindowManagerService添加窗口。
  4. updateViewLayout。通过ViewRootImpl 进程合成绘制,通知SurfaceFlinger渲染。
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/followYouself/article/details/125176288