Android--Activity的创建过程(二)

  • ActivityManagerService中的startProcessLocked()方法

创建新进程的消息进入到AMS的startProcessLocked()中,然后直接传入到ProcessList中的startProcessLocked()方法中

  1. 首先调用ProcessList的startProcessLocked方法来启动进程,需要传入进程名、应用程序信息、是否已知进程已经死亡、意图标志、宿主记录、Zygote策略标志、是否允许在系统启动时启动进程、是否隔离进程、是否保留大进程等参数;
  2. 然后返回一个ProcessRecord对象,这个对象代表了新启动的进程。
    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 */);
    }

  • ProcessList中的startProcessLocked()方法

ProcessList内部会创建一个AppZygote对象,然后孵化出新的进程;

该方法接收14个创建进程的参数,包括进程名、应用程序信息、是否已知为死亡状态、意图标志、宿主记录、Zygote策略标志、是否允许在系统启动时运行、是否隔离、隔离UID、是否保持大进程、ABI覆盖、入口点、入口点参数和崩溃处理程序。

  1. 首先检查是否需要创建新的进程。如果不需要创建新进程,它会检查进程是否已经存在并且处于活动状态。如果进程已经存在并且处于活动状态,它会将应用程序信息添加到进程中并返回该进程。如果进程已经存在但处于非活动状态,它会杀死该进程并创建一个新的进程记录。

  2. 如果需要创建新进程,它会创建一个新的进程记录,并将应用程序信息添加到该进程中。然后,它会检查系统是否准备好运行新进程。如果系统尚未准备好运行新进程,它会将进程置于等待状态。最后,它会调用startProcessLocked()方法来启动新进程,并根据启动结果返回相应的进程记录或null。

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

            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
                if (mService.mAppErrors.isBadProcessLocked(info)) {
                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
                            + "/" + info.processName);
                    return null;
                }
            } else {
                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
                        + "/" + info.processName);
                mService.mAppErrors.resetProcessCrashTimeLocked(info);
                if (mService.mAppErrors.isBadProcessLocked(info)) {
                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
                            UserHandle.getUserId(info.uid), info.uid,
                            info.processName);
                    mService.mAppErrors.clearBadProcessLocked(info);
                    if (app != null) {
                        app.bad = false;
                    }
                }
            }
        } else {
            app = null;
        }
        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
                + " app=" + app + " knownToBeDead=" + knownToBeDead
                + " thread=" + (app != null ? app.thread : null)
                + " pid=" + (app != null ? app.pid : -1));
        ProcessRecord precedence = null;
        if (app != null && app.pid > 0) {
            if ((!knownToBeDead && !app.killed) || app.thread == null) {
                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
                app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
                checkSlow(startTime, "startProcess: done, added package to proc");
                return app;
            }
            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
            checkSlow(startTime, "startProcess: bad proc running, killing");
            ProcessList.killProcessGroup(app.uid, app.pid);
            checkSlow(startTime, "startProcess: done killing old proc");

            Slog.wtf(TAG_PROCESSES, app.toString() + " is attached to a previous process");
            precedence = app;
            app = null;
        }

        if (app == null) {
            checkSlow(startTime, "startProcess: creating new process record");
            app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord);
            if (app == null) {
                Slog.w(TAG, "Failed making new process record for "
                        + processName + "/" + info.uid + " isolated=" + isolated);
                return null;
            }
            app.crashHandler = crashHandler;
            app.isolatedEntryPoint = entryPoint;
            app.isolatedEntryPointArgs = entryPointArgs;
            if (precedence != null) {
                app.mPrecedence = precedence;
                precedence.mSuccessor = app;
            }
            checkSlow(startTime, "startProcess: done creating new process record");
        } else {
            app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats);
            checkSlow(startTime, "startProcess: added package to existing proc");
        }
        if (!mService.mProcessesReady
                && !mService.isAllowedWhileBooting(info)
                && !allowWhileBooting) {
            if (!mService.mProcessesOnHold.contains(app)) {
                mService.mProcessesOnHold.add(app);
            }
            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
                    "System not ready, putting on hold: " + app);
            checkSlow(startTime, "startProcess: returning with proc on hold");
            return app;
        }

        checkSlow(startTime, "startProcess: stepping in to startProcess");
        final boolean success =
                startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
        checkSlow(startTime, "startProcess: done starting proc!");
        return success ? app : null;
    }

  • ProcessList中的startProcessLocked()方法

启动新进程的过程:

  1. 上面一个ProcessList中的startProcessLocked()方法接收了14个参数,进行了一些操作之后调用startProcessLocked()方法传递了4个参数进去来启动新进程;
  2. 接收4个参数的startProcessLocked()方法直接 return startProcessLocked()方法,增加了一些参数默认值,跳转到了接收7个参数的startProcessLocked()方法;
  3. 接收7个参数的startProcessLocked()方法又进行了一些处理,最后还是返回一个startProcessLocked()方法,并传入13个参数;

接收13个参数的startProcessLocked()方法:

  1. 首先设置进程记录的一些属性,如禁用的兼容性更改、启动参数和使用包装器,将进程记录添加到待处理启动列表中;
  2. 根据系统配置,可以异步启动进程或同步启动进程,如果异步启动进程,它会将进程启动消息发布到处理程序中,并返回true;如果选择同步启动进程,它会尝试startProcess启动进程,并在成功时处理进程启动结果,否则会强制停止应用程序并返回false;
    boolean startProcessLocked(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) {
        app.pendingStart = true;
        app.killedByAm = false;
        app.removed = false;
        app.killed = false;
        if (app.startSeq != 0) {
            Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
                    + " with non-zero startSeq:" + app.startSeq);
        }
        if (app.pid != 0) {
            Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
                    + " with non-zero pid:" + app.pid);
        }
        app.mDisabledCompatChanges = null;
        if (mPlatformCompat != null) {
            app.mDisabledCompatChanges = mPlatformCompat.getDisabledChanges(app.info);
        }
        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
        app.setStartParams(uid, hostingRecord, seInfo, startTime);
        app.setUsingWrapper(invokeWith != null
                || Zygote.getWrapProperty(app.processName) != null);
        mPendingStarts.put(startSeq, app);

        if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
            if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
                    "Posting procStart msg for " + app.toShortString());
            mService.mProcStartHandler.post(() -> handleProcessStart(
                    app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
                    requiredAbi, instructionSet, invokeWith, startSeq));
            return true;
        } else {
            try {
                final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                        entryPoint, app,
                        uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
                        requiredAbi, instructionSet, invokeWith, startTime);
                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                        startSeq, false);
            } catch (RuntimeException e) {
                Slog.e(ActivityManagerService.TAG, "Failure starting process "
                        + app.processName, e);
                app.pendingStart = false;
                mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
                        false, false, true, false, false, app.userId, "start failure");
            }
            return app.pid > 0;
        }
    }

  • ProcessList中的startProcess()方法

ProcessList中的startProcess()方法的作用是启动一个新的进程;

  1. 检查是否需要使用WebView Zygote或App Zygote来启动新进程。
  2. 如果需要,为新进程创建一个App Zygote实例。
  3. 根据不同的条件,调用Process类的start方法来启动新进程。
  4. 返回一个ProcessStartResult对象,表示新进程的启动结果。
    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 {

            ...

            final Process.ProcessStartResult startResult;
            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.mDisabledCompatChanges,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
            } 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.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
                        false, false,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
            } else {

            ...

            }
         }
      }

从系统服务回到Activity线程中
  • ActivityThread.main()

创建好新启动的进程后就走到了ActivityThread的主函数main()方法:

  1. 开始跟踪ActivityManager的启动过程。
  2. 安装选择性系统调用拦截。
  3. 关闭CloseGuard,因为它可能会产生很多不必要的日志。
  4. 初始化当前用户的环境。
  5. 确保TrustedCertificateStore在正确的位置查找CA证书。
  6. 调用每个进程的主要模块初始化。
  7. 设置进程参数。
  8. 准备主线程的Looper。
  9. 从命令行中查找PROC_START_SEQ_IDENT的值,如果提供了该值,它将以"seq=114"的格式出现。
  10. 创建一个新的ActivityThread实例,并将其附加到主线程。
  11. 如果sMainThreadHandler为null,则将其设置为新创建的ActivityThread的Handler。
  12. 如果需要,启用消息日志记录。
  13. 结束跟踪ActivityManager的启动过程。
  14. 进入主线程的Looper循环。
  15. 如果主线程循环意外退出,则抛出一个运行时异常。

其中主要步骤是:

  1. Looper.prepareMainLooper()初始化looper;
  2. new ActivityThread()创建一个新的ActivityThread实例,thread.attach将其附加到主线程上。
    public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

        // Install selective syscall interception
        AndroidOs.install();

        // CloseGuard defaults to true and can be quite spammy.  We
        // disable it here, but selectively enable it later (via
        // StrictMode) on debug builds, but using DropBox, not logs.
        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);

        // Call per-process mainline module initialization.
        initializeMainlineModules();

        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();

        // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
        // It will be in the format "seq=114"
        long startSeq = 0;
        if (args != null) {
            for (int i = args.length - 1; i >= 0; --i) {
                if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                    startSeq = Long.parseLong(
                            args[i].substring(PROC_START_SEQ_IDENT.length()));
                }
            }
        }
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

        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");
    }

  • ActivityThread的attach()方法

该方法主要是把新创建的目标Activity对应的进程关联到AMS中;

  1. attachApplication()传入的mAppThread类型是ApplicationThread,是IApplicationThread的Binder接口本地实现类,用来接收AMS等其他进程的信息;
  2. mgr.attachApplication(mAppThread, startSeq)是一次IPC过程,会调用AMS服务中对应的方法;
    private void attach(boolean system, long startSeq) {

        ...

        if (!system) {
            ...
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread, startSeq);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }

            ...

        }

        ...


  • AMS的attachApplicationLocked()方法

AMS处理attachApplication的调用,主要是把进程名等进程的信息,通过IApplicationThread这个Binder接口传递给新创建的进程;

    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
        ProcessRecord app;

        ...

if (app.isolatedEntryPoint != null) {
                // This is an isolated process which should just call an entry point instead of
                // being bound to an application.
                thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
            } else if (instr2 != null) {
                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.compat, getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.mDisabledCompatChanges);
            } else {
                thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.compat, getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.mDisabledCompatChanges);
            }

        ...


  • RootWindowContainer的startActivityForAttachedApplicationIfNeeded()方法

在执行完bindApplication之后,AMS会继续调用到RootWindowContainer里面的realStartActivityLocked方法,找到与此进程相关联的Activity,并打开此Activity;

   private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
            WindowProcessController app, ActivityRecord top) {
        if (r.finishing || !r.okToShowLocked() || !r.visibleIgnoringKeyguard || r.app != null
                || app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
            return false;
        }

        try {
            if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,
                    true /*checkConfig*/)) {
                mTmpBoolean = true;
            }
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception in new application when starting activity "
                    + top.intent.getComponent().flattenToShortString(), e);
            mTmpRemoteException = e;
            return true;
        }
        return false;
    }

  • ActivityStackSupervisor的realStartActivityLocked()方法

AMS调用ActivityStackSupervisor的realStartActivityLocked()方法找到与进程相关联的Activity,这里的ClientTransaction,具备IPC的能力,通过内部的IApplicationThread Binder接口,会把自己作为参数传递给对应要操作的进程。本次的事务处理,ClientTransaction添加了一个LaunchActivityItem,说明要显示Activity的意图,打开目标Activity。

    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {

            ...

                final DisplayContent dc = r.getDisplay().mDisplayContent;
                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.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                        r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));

                ...
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);

  • ActivityThread的bindApplication()方法

应用进程首先会接收到AMS对bindApplication的回调,接收的位置是在ActivityThread内部,它是IApplicationThread的本地实现;

  1. bindApplication接收到来自AMS的绑定信息,主要是processName和ApplicationInfo;
  2. 最后给主线程Handler H 发送送一条信息,进程接收到的信息交由H处理;
        public final void bindApplication(String processName, ApplicationInfo appInfo,
                ProviderInfoList providerList, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                String buildSerial, AutofillOptions autofillOptions,
                ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges) {

            ...

            setCoreSettings(coreSettings);\
            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;
            data.providers = providerList.getList();
            ...
            sendMessage(H.BIND_APPLICATION, data);

  • ActivityThread的主线程H

主线程H接收bindApplication发送的BIND_APPLICATION消息,处理应用程序绑定;

    class H extends Handler {
        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;

              ...


  • ActivityThread的handleBindApplication()方法

handleBindApplication方法用来处理应用程序绑定,该方法初始化了Android的上下文环境,同时还初始化了Application,并且回调了Application的onCreat()方法。其中关键代码行:

  1. setArgV0进程设置名称;
  2. setProcessPackageName设置包名;
  3. createAppContext创建ContextImpl;
  4. 创建mInstrumentation
  5. makeApplication利用反射创建了Manifest文件中对应的Application
  6. 调用Application的onCreat()方法
    private void handleBindApplication(AppBindData data) {

        ...

        Process.setArgV0(data.processName);
        ...
        VMRuntime.setProcessPackageName(data.appInfo.packageName);

        ...

            final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
                    appContext.getOpPackageName());

            try {
                final ClassLoader cl = instrContext.getClassLoader();
                mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
            } catch (Exception e) {
              ...
            }

            final ComponentName component = new ComponentName(ii.packageName, ii.name);
            mInstrumentation.init(this, instrContext, appContext, component,
                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);

        ...

        Application app;
       ...
        try {
            app = data.info.makeApplication(data.restrictedBackupMode, null);
           ...
            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }
            catch (Exception e) {
               ...
            }
            try {
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
               ...
            }

  • ActivityThread的ApplicationThread 类

应用进程会收到ClientTransaction的方法回调;

    private class ApplicationThread extends IApplicationThread.Stub {

        ...

        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }

        ...

    }

    ...

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }


  • TransactionExecutor的executeCallbacks类

在接收到scheduleTransaction的回调之后,还是会把消息给到ActivityThread的H处理,H会把ClientTransaction这个消息给到TransactionExecutor处理;

TransactionExecutor会去执行ClientTransactionItem 内部的逻辑;

    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();

        ...

for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
            final int postExecutionState = item.getPostExecutionState();
            final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                    item.getPostExecutionState());
            if (closestPreExecutionState != UNDEFINED) {
                cycleToPath(r, closestPreExecutionState, transaction);
            }

            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);

        ...


  • LaunchActivityItem类

execute中的client参数就是ActivityThread,ActivityThread实现了ClientTransactionHandler,这里就调用到了ActivityThread的handleLaunchActivity方法,同时把Activity的相关信息封装成了ActivityClientRecord 数据结构作为参数传递;

public class LaunchActivityItem extends ClientTransactionItem {

    ...

    @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, mFixedRotationAdjustments);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

    ...


  • ActivityThread的handleLaunchActivity()方法

该方法主要功能是处理启动Activity的操作:

  1. 首先,调用unscheduleGcIdler()方法取消垃圾回收的调度。
  2. 设置mSomeActivitiesChanged为true,表示有活动发生了变化。
  3. 如果r.profilerInfo不为空,则设置Profiler并开始分析。
  4. 确保运行的是最新的配置,如果需要的话预加载硬件渲染器。
  5. 初始化WindowManagerGlobal。
  6. 提示GraphicsEnvironment一个进程上的活动正在启动。
  7. 调用performLaunchActivity方法执行实际的启动操作,并将返回的Activity对象赋值给变量a。
  8. 如果a不为空,则进行以下操作:
    创建一个新的Configuration对象,并将其赋值给r.createdConfig。
    报告尺寸配置信息。
    如果r.activity未完成且pendingActions不为空,则设置pendingActions的旧状态、恢复实例状态和调用onPostCreate标志。
  9. 如果a为空,则表示有错误发生,通知ActivityManager停止当前进程。
  10. 最后,返回Activity对象a。
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
        mSomeActivitiesChanged = true;

        if (r.profilerInfo != null) {
            mProfiler.setProfiler(r.profilerInfo);
            mProfiler.startProfiling();
        }

        // Make sure we are running with the most recent config.
        handleConfigurationChanged(null, null);

        if (localLOGV) Slog.v(
            TAG, "Handling launch of " + r);

        // Initialize before creating the activity
        if (!ThreadedRenderer.sRendererDisabled
                && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
            HardwareRenderer.preload();
        }
        WindowManagerGlobal.initialize();

        // Hint the GraphicsEnvironment that an activity is launching on the process.
        GraphicsEnvironment.hintActivityLaunch();

        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 {
                ActivityTaskManager.getService()
                        .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }

        return a;
    }

  • ActivityThread的performLaunchActivity()方法

performLaunchActivity方法执行实际的启动Activity操作:

  1. 首先会调用Activity的onCreate方法来创建Activity实例;
  2. 根据传入的Intent对象,可能会进行一些额外的处理,例如启动其他Activity、发送广播等;
  3. 将创建的Activity实例返回给调用者。

performLaunchActivity方法只是执行启动Activity的操作,具体的生命周期管理、消息传递等功能是由ActivityThread类的其他方法来完成的。

    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }

        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            // AppComponentFactory利用反射生成Activity
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
            if (localLOGV) Slog.v(
                    TAG, r + ": app=" + app
                    + ", appName=" + app.getPackageName()
                    + ", pkg=" + r.packageInfo.getPackageName()
                    + ", comp=" + r.intent.getComponent().toShortString()
                    + ", dir=" + r.packageInfo.getAppDir());

            if (activity != null) {
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }

                // Activity resources must be initialized with the same loaders as the
                // application context.
                appContext.getResources().addLoaders(
                        app.getResources().getLoaders().toArray(new ResourcesLoader[0]));

                appContext.setOuterContext(activity);
                // activity关联相关的信息,包括创建PhoneWindow
                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 (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                checkAndBlockForNetworkAccess();
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    // 回调Activity的OnCreate回调方法
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
                mLastReportedWindowingMode.put(activity.getActivityToken(),
                        config.windowConfiguration.getWindowingMode());
            }
            r.setState(ON_CREATE);

            // updatePendingActivityConfiguration() reads from mActivities to update
            // ActivityClientRecord which runs in a different thread. Protect modifications to
            // mActivities to avoid race.
            synchronized (mResourcesManager) {
                mActivities.put(r.token, r);
            }

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }


在回调了OnCreate方法之后,目标Activity就算创建完成了;
下一步就是在设置contentview,attach到WMS上显示了。

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
img
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓(文末还有ChatGPT机器人小福利哦,大家千万不要错过)

PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题
图片

  • 12
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值