Activity启动过程分析(Android P)

本章我们来分析Activity的启动过程,我们先从熟悉的startActivity方法来开始分析。

startActivity的实现

要启动一个Activity,无论是从Lanuch启动,还是App内部启动,都需要调用startActivity()方法来实现。

startActivity定义

startAcrtivity方法是在Context中定义的:

    public abstract void startActivity(Intent var1);

    public abstract void startActivity(Intent var1, @Nullable Bundle var2);

这是两个抽象方法,需要子类来实现。

Context的继承关系

Context的继承关系中,有2个子类是跟startActivity启动有关的:Activity类和ContextImpl类。

Activity中的startActivity方法

绝大部分的Activity启动都是从Activity开始的,所以我们首先来看Activity的继承关系:

Activity–>ContextThemeWrapper–>ContextWrapper–>Context。

Activity中的startActivity方法实现:

/frameworks/base/core/java/android/app/Activity.java

    @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }
    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

这里我们看到了,它复写了父类的startActivity方法来实现Activity启动相关逻辑。

ContxtImpl中的startActivity方法

ContxtImpl中的startActivity方法:

/frameworks/base/core/java/android/app/ContextImpl.java

    @Override
    public void startActivity(Intent intent) {
        warnIfCallingFromSystemProcess();
        startActivity(intent, null);
    }
    @Override
    public void startActivity(Intent intent, Bundle options) {
        warnIfCallingFromSystemProcess();

        // Calling start activity from outside an activity without FLAG_ACTIVITY_NEW_TASK is
        // generally not allowed, except if the caller specifies the task id the activity should
        // be launched in.
        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0
                && options != null && ActivityOptions.fromBundle(options).getLaunchTaskId() == -1) {
            throw new AndroidRuntimeException(
                    "Calling startActivity() from outside of an Activity "
                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
                    + " Is this really what you want?");
        }
        mMainThread.getInstrumentation().execStartActivity(
                getOuterContext(), mMainThread.getApplicationThread(), null,
                (Activity) null, intent, -1, options);
    }

通过代码逻辑以及注释,我们了解到,ContextImpl的startActivity是为了在Activity之外启动Activity提供的方法,并且在这里启动Activity需要满足一定的条件,否则会报错。

满足以下2个条件之一即可启动:

  1. startActivity的Intent参数必须设置Intent.FLAG_ACTIVITY_NEW_TASK标志位。
  2. 或者第二个参数options为将要启动的Activity指定了TaskId(工作栈id)。

结论

通过上面分析,我们知道了:

  • startActivity方法都是实现自Context的抽象方法。
  • Context的主要实现startActivity子类包含了Activity类和ContextImpl类。
  • 通常我们启动Activity都是通过指向Activity类的startActivity方法实现的。
  • 如果我们想在Activity之外来启动一个Activity,需要使用ContextImpl的startActivity方法,并且设置Flag参数Intent.FLAG_ACTIVITY_NEW_TASK标志位或者为Activity指定一个工作栈。
  • 其实无论哪种启动方法,最终都会调用到Instrumentation类的实例方法execStartActivity来执行启动过程的。

我们接下来就从Activity类的startActivity方法来开始分析Activity的启动过程。

Activity的启动过程——准备阶段

Activity的启动过程涉及到Activity所在的Client端,以及ASM等相关Server端。

准备阶段发生在Client端,为接下来的启动过程做准备处理。

Activity的startActivity方法

首先我们来看Activity的startActivity方法:

    @Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }
    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

经过调用,转到了startActivityForResult方法中:

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
        } else {
            //历史版本的嵌套Activity使用,现已废弃
            ……
        }
    }
参数:
  • 参数requestCode表示请求的code标识,如果调用者期望返回结果(调用startActivityForResult启动Activity),则这里是一个大于0的值;如果使用startActivity启动,则值为-1。

  • options代表启动时的附加选项,多数情况下options的值为null。

方法逻辑分析:
  1. 对options参数进行处理。
  2. 调用Instrumentation的execStartActivity方法来启动Activity。
  3. 如果启动成功,调用ActivityThread实例方法sendActivityResult进一步处理。
  4. 之后调用cancelInputsAndStartExitTransition来取消挂起的input相关事件,如果activity之间有切换动画,则开始执行。

我们来看下涉及的几个成员变量:

  • mParent

方法首先判断了mParent是否为null,那么这个mParent是怎么来的呢?

通过源码查找可以发现,mParent赋值过程:LocalActivityManager类的startActivity–>调用moveToState–>调用ActivityThread.startActivityNow方法,这时会把mParent的值传递进去,最终赋值给mParent属性。

那么LocalActivityManager类是做什么的呢?我们通过注释发现它已经被废弃的一个类,在低版本的Android系统上,之前使用它来管理多Activity嵌套的问题,相关组件如ActivityGroup的子组件等。目前这个嵌套Activity的方案已经被Fragement替代掉了,我们这里就不做过多分析了。

  • mStartedActivity

该成员变量表示Activity是否已经创建完成,它用于判断Activity内容是否要展示在Window上。

Instrumentation的execStartActivity方法

我们继续分析Instrumentation的execStartActivity方法:

/frameworks/base/core/java/android/app/Instrumentation.java

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        Uri referrer = target != null ? target.onProvideReferrer() : null; //获取调用者的referrer
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        if (mActivityMonitors != null) { //判断ActivityMonitors列表是否为空
            ……
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
逻辑分析:
  1. 从调用startActivity的来源Activity对象中,获得referrer值,它存储在Activity对象的mReferrer属性中,该属性表示调用者的来源(值为包名)。不过在此处,通过onProvideReferrer方法如果没在子类中复写,则返回值为null。

  2. 如果referrer不为空,则添加到intent的Intent.EXTRA_REFERRER值中。

  3. 判断ActivityMonitors列表是否为空,ActivityMonitors类用于InstrumentationTest的相关测试类。

    当一个新Activity创建,ActivityMonitor就会被检查,如果匹配,它的点击次数(mHits)就会被更新。如果调用结束,一个结果(ActivityResult)就会被回传。
    ActivityMonitor也可以通过waitForActivity用来等待Activity的创建成功,将会返回一个匹配Activity的对象。

  4. 设置intent相关数据。

  5. 调用AMS的startActivity启动Activity。

  6. 最后对返回结果进行处理。

以上过程都是在我们的Clent进程进行的。

Activity的启动过程——Server端启动、校验等过程

接下来的逻辑处理发生在AMS等相关服务进程。我们首先来看AMS的的startActivity方法。

ActivityManagerService的startActivity方法

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

    @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    }

    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
            boolean validateIncomingUser) {
        enforceNotIsolatedCaller("startActivity");//检验进程是否是“隔离”进程,如果是,则抛出error

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

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

    }

这里的逻辑比较简单,进行一些处理,然后调用ActivityStartController的obtainStarter方法,该方法返回一个ActivityStarter对象。ActivityStarter负责Activity启动相关操作,这里调用了ActivityStarter对象的execute方法来执行。

ActivityStarter的相关方法

execute方法:

/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

    int execute() {
        try {
            // TODO(b/64750076): Look into passing request directly to these methods to allow
            // for transactional diffs and preprocessing.
            if (mRequest.mayWait) {
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                        mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                        mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            } else {
                return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                        mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                        mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                        mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                        mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                        mRequest.outActivity, mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            }
        } finally {
            onExecutionComplete();
        }
    }

如果是正常启动Activity,这里会直接调用startActivityMayWait方法。

private int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
            int userId, TaskRecord inTask, String reason,
            boolean allowPendingRemoteAnimationRegistryLookup) {
        ……
        处理调用者进程uid、pid等信息;处理短暂安装者程序启动Activity。

        //1. 这里调用ActivityStackSupervisor的resolveIntent来解析Intent信息(它又调用了AMS的getPackageManagerInternalLocked().resolveIntent)
        ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
                0 /* matchFlags */,
                        computeResolveFilterUid(
                                callingUid, realCallingUid, mRequest.filterCallingUid));
        if (rInfo == null) {
            ……
        }
        // 2. 调用ActivityStackSupervisor的resolveActivity方法获得将要启动的Activity信息。
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

        synchronized (mService) {
            final ActivityStack stack = mSupervisor.mFocusedStack;
            stack.mConfigWillChange = globalConfig != null
                    && mService.getGlobalConfiguration().diff(globalConfig) != 0;
            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                    "Starting activity when config will change = " + stack.mConfigWillChange);

            final long origId = Binder.clearCallingIdentity();
            ……
            //3. 对重量级进程进行相关处理。
            ……
            final ActivityRecord[] outRecord = new ActivityRecord[1];
            //4. 调用startActivity启动Activity
            int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                    ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
                    allowPendingRemoteAnimationRegistryLookup);

            Binder.restoreCallingIdentity(origId);

            ……

            if (outResult != null) {
                ……
                5. 结果回调相关处理
                ……
            }

            mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]);
            return res;
        }
    }
逻辑分析
  1. 这里调用ActivityStackSupervisor的resolveIntent来解析Intent信息(它又调用了AMS的getPackageManagerInternalLocked().resolveIntent)。

    getPackageManagerInternalLocked()的返回值是一个PMS的本地引用,调用它的resolveIntent方法去解析安装包中的Manifest信息,从中选择出最匹配的一个Activity,并把引用付给ResolveInfo对象,最终把ResolveInfo对象返回。

  2. 调用ActivityStackSupervisor的resolveActivity方法获得将要启动的Activity信息,这一步中的Activity信息,是从ResolveInfo对象中直接获取的,如果存在,则对Intent对象进行一些设置(例如setComponent等)。

  3. 对标识为重量级进程的,进行相关处理,普通应用不会进行此操作,我们不做过多关注。

  4. 调用startActivity启动Activity。

  5. 结果回调相关处理。

startActivity方法,在它内部又调用了另一个startActivity方法,我们直接来看第二个startActivity方法:

    private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            SafeActivityOptions options,
            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
            TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
        ……
        处理uid、pid等信息
        ……
        ……
        处理ActivityRecord对象
        

        ……
        一些验证逻辑及错误处理
        ……

        检查Activity是否允许启动的权限
        ……

        ……

        //拦截处理


        ……
        如果权限需要审阅,我们将会挂起Intent启动,将会在审阅之后继续进行。

        ……
        针对ephemeral app进行处理,首先执行应用安装
        ……
        创建ActivityRecord对象,并给它的属性赋值
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, checkedOptions, sourceRecord);
        ……

        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                true /* doResume */, checkedOptions, inTask, outActivity);
    }

这个方法中,主要执行了一些校验逻辑。最后又调用了另一个重载的startActivity方法,我们继续来看:

    private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity) {
        int result = START_CANCELED;
        try {
            mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        } finally {
            ……
            //相关清除操作
        }

        postStartActivityProcessing(r, result, mTargetStack);

        return result;
    }

这里调用了startActivityUnchecked方法来启动Activity:

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {

        //设置ActivityStarter的相关属性

        ……

        ActivityRecord reusedActivity = getReusableIntentActivity(); //查找是否存在可以重用的Activity记录,返回ActivityRecord对象

        
        if (reusedActivity != null) {
            ……
        }

        ……

        // 如果顶部的Activity和我们将要启动的相同,则检查该Activity是否只允许启动一次(设置了SINGLE_TOP或SINGLE_TASK)
        final ActivityStack topStack = mSupervisor.mFocusedStack;
        final ActivityRecord topFocused = topStack.getTopActivity();
        final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
        final boolean dontStart = top != null && mStartActivity.resultTo == null
                && top.realActivity.equals(mStartActivity.realActivity)
                && top.userId == mStartActivity.userId
                && top.app != null && top.app.thread != null
                && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
                || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
        if (dontStart) {
            ……
            return START_DELIVERED_TO_TOP;
        }

        ……
        获得或创建目标Activity所使用的Task。
        ……
        mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
                mOptions);
        if (mDoResume) {
            ……
            启动处理
            
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                ……
                mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                // Go ahead and tell window manager to execute app transition for this activity
                // since the app transition will not be triggered through the resume channel.
                mService.mWindowManager.executeAppTransition();
            } else {
                ……
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else if (mStartActivity != null) {
            mSupervisor.mRecentTasks.add(mStartActivity.getTask());
        }
        mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);

        mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
                preferredLaunchDisplayId, mTargetStack);

        return START_SUCCESS;
    }
逻辑分析:
  1. 设置当前ActivityStarter对象的各个属性,对其进行初始化处理。
  2. 查找是否有可重用的Activity,并返回对应的ActivityRecord对象,如果存在,则进一步处理。
  3. 判断是Activity任务栈的启动模式,并进行相关处理。
  4. 获取Activity将要使用的任务栈的实例。
  5. 调用任务栈实例的startActivityLocked来执行。
  6. 调用ActivityStackSupervisor对象的resumeFocusedStackTopActivityLocked方法进行启动处理。

ActivityStack的startActivityLocked方法

逻辑分析
  • ActivityStack的startActivityLocked方法(/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java)主要是生成相应的TaskRecord对象,以及对任务栈进行相关处理。
  • ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法(/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java),调用ActivityStack的resumeTopActivityUncheckedLocked方法。
  • ActivityStack的resumeTopActivityUncheckedLocked方法调用了它的resumeTopActivityInnerLocked方法。
  • resumeTopActivityInnerLocked方法调用了ActivityStackSupervisor的实例方法startSpecificActivityLocked。该方法调用了realStartActivityLocked方法。

ActivityStackSupervisor的realStartActivityLocked方法

    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
            ……
                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                        r.appToken);
                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, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                        profilerInfo));

                // Set desired final state.
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
                } else {
                    lifecycleItem = PauseActivityItem.obtain();
                }
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

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

这里创建了一个事务来创建Activity,然后由mService.getLifecycleManager().scheduleTransaction来启动该事务。

mService是AMS,getLifecycleManager方法返回一个ClientLifecycleManager对象,执行它的scheduleTransaction方法,经过内部一系列调用,最终是调用了ApplicationThread对象的scheduleTransaction方法。

ApplicationThread对象的scheduleTransaction方法调用了ActivityThread的scheduleTransaction方法,该方法是定义在ActivityThread的父类ClientTransactionHandler中,它的实现如下:

    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

后续步骤会经过一系列跳转操作,过程如下:

  1. ActivityThread的Handler对象对ActivityThread.H.EXECUTE_TRANSACTION消息进行处理,调用了TransactionExecutor.execute(transaction)方法。
  2. TransactionExecutor.execute方法,调用了executeCallbacks方法,对之前注册进来的callback进行处理。
  3. 这里取出其中的ClientTransactionItem ,并执行ClientTransactionItem的execute方法。
  4. ClientTransactionItem是一个抽象类,它的实现类是LaunchActivityItem(在ActivityStackSupervisor的realStartActivityLocked方法中可以看到)。
  5. LaunchActivityItem的execute方法中,会执行ClientTransactionHandler的handleLaunchActivity方法。这里的ClientTransactionHandler是在execute方法中作为参数传递进来的,之前又是通过TransactionExecutor的构造函数传递的参数,它是其实就是ActivityThread对象。
  6. 这里终于到了ActivityThread的对象方法handleLaunchActivity中了。

正式创建、启动Activity

经过复杂的逻辑调用,现在终于到了正式创建和启动Activity的阶段了。该过程又回到了Client进程中进行的。

ActivityThread的handleLaunchActivity方法:

    /**
     * Extended implementation of activity launch. Used when server requests a launch or relaunch.
     */
    @Override
    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(); //跳过GC
        mSomeActivitiesChanged = true;
        ……
        // 更新Configuration
        handleConfigurationChanged(null, null);

        //创建Activity之前,做一些初始化工作
        if (!ThreadedRenderer.sRendererDisabled) {
            GraphicsEnvironment.earlyInitEGL();
        }
        WindowManagerGlobal.initialize();
        //执行Activity创建过程
        final Activity a = performLaunchActivity(r, customIntent);

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

        return a;
    }

在这里调用performLaunchActivity方法正式启动Activity。

performLaunchActivity方法:

    /**  Core implementation of activity launch. */
    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);
        }
        //获取Activity对应的组件信息
        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);
        }
        //创建Activity的Context对象
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader(); //获得ClassLoader对象
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent); //创建Activity对象
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            ……
        }

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

            ……
            if (activity != null) {
                ……
                appContext.setOuterContext(activity);
                //调用activity的attach方法
                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);

                ……
                //调用onCreate方法
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ……
                r.activity = activity;
            }
            r.setState(ON_CREATE);
            //将Activity添加到mActivityes列表中
            mActivities.put(r.token, r);

        } 
        ……

        return activity;
    }
逻辑分析:
  1. 获取Activity对应的组件信息。
  2. 创建Activity的Context对象。
  3. 获得ClassLoader对象。
  4. 调用Instrumentation的newActivity方法创建Activity对象。newActivity方法仅仅是反射调用,创建一个Activity实例。
  5. Activity创建成功后,调用它的attach方法。在attach方法中,创建PhoneWindow等操作。
  6. 之后再调用Instrumentation的callActivityOnCreate方法,callActivityOnCreate调用activity.performCreate方法,在这里又切换回了Activity中,在performCreate中,最终调用到onCreate,我们熟悉的Activity生命周期方法。
  7. 最后将该Activity添加到mActivityes列表中。
原创文章 20 获赞 2 访问量 5104

猜你喜欢

转载自blog.csdn.net/u011578734/article/details/105689516