Android源码阅读分析:从Activity开始(一)——启动流程

从Activity开始(一)——启动流程


(注:源代码为android-8.1)

启动流程

  通过我们常用的方法调用开始逐步向下探索。
  
  通常来说,我们使用的最简单的启动Activity方法是startActivity(Intent intent),该方法的实现源码为:

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

@Override
public void startActivity(Intent intent) {
    this.startActivity(intent, null);
}

  这里调用了同名重载函数startActivity(Intent intent, @Nullable Bundle options),该方法的源码实现为:

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

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

  从这里我们发现,即使是普通的启动Activity方法,也是调用了startActivityForResult(Intent intent, int requestCode, Bundle options)方法。其中requestCode < 0时,不会调用onActivityResult()方法。
  该方法源码实现如下:

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

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 {
        if (options != null) {
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}

  在这个方法中会通过判断mParent是否为空分为两支。该变量只有在Acitivity为内置Activity的时候才不为空,例如
TabActivity
。在该方法中,关键的操作为mInstrumentation.execStartActivity。可以看出,启动Activity其实是通过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) {
    ...
    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;
}

  这里我们先追踪一下ActivityManager.getService()方法。

(frameworks/base/core/java/android/app/ActivityManager.java)

public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @Override
            protected IActivityManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            }
        };

  这里的意思就是获取了IActivityManager类的一个单例。在创建IActivityManager单例时,首先获取了名为Context.ACTIVITY_SERVICEService引用,然后通过asInstance方法转换成IActivityManager的对象。

  ActivityManagerService继承了IActivityManager.Stub,说明了是ActivityManagerService作为服务端,处理startActivity方法。

(frameworks/base/core/java/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());
}

  这里并没有什么其他逻辑,直接调用startActivityAsUser方法。继续向下分析。

(frameworks/base/core/java/android/server/am/ActivityManagerService.java)

@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) {
    enforceNotIsolatedCaller("startActivity");
    userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
            userId, false, ALLOW_FULL_ONLY, "startActivity", null);
    // TODO: Switch to user app stacks here.
    return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
}

  这里也只是多添加了一些userId的安全性判断。之后继续调用了mActivityStarter.startActivityMayWait方法。

(frameworks/base/core/java/android/server/am/ActivityStarter.java)

final 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, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            TaskRecord inTask, String reason) {
    ...
    synchronized (mService) {
        ...
        int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor,
                    resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
                    reason);
        ...
        return res;
    }
    ...
}

  ActivityStarter类是启动Activity的控制器,它集中了所有确定如何将intentfalgs转化为Activity的逻辑。继续跟踪调用方法startActivityLocked

(frameworks/base/core/java/android/server/am/ActivityStarter.java)

int startActivityLocked(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,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask, String reason) {

    if (TextUtils.isEmpty(reason)) {
        throw new IllegalArgumentException("Need to specify a reason.");
    }
    mLastStartReason = reason;
    mLastStartActivityTimeMs = System.currentTimeMillis();
    mLastStartActivityRecord[0] = null;

    mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                inTask);

    if (outActivity != null) {
        // mLastStartActivityRecord[0] is set in the call to startActivity above.
        outActivity[0] = mLastStartActivityRecord[0];
    }

    // Aborted results are treated as successes externally, but we must track them internally.
    return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
}

  这里继续调用了startActivity方法。

(frameworks/base/core/java/android/server/am/ActivityStarter.java)

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,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask) {
    int err = ActivityManager.START_SUCCESS;
    // Pull the optional Ephemeral Installer-only bundle out of the options early.
    final Bundle verificationBundle = options != null ? options.popAppVerificationBundle() : null;
    ProcessRecord callerApp = null;
    if (caller != null) {
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            Slog.w(TAG, "Unable to find app for caller " + caller
                        + " (pid=" + callingPid + ") when starting: "
                        + intent.toString());
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }
    ...
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
}

  此处的caller是跟随一路调用传递而来的参数,指向的是ApplicationThread对象。之后继续调用同名重载函数。

(frameworks/base/core/java/android/server/am/ActivityStarter.java)

 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);
    }
    ...
    return result;
}

  这里紧接着调用了startActivityUnchecked方法。

(frameworks/base/core/java/android/server/am/ActivityStarter.java)

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
    ...
    if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
        // 新任务
        newTask = true;
        result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, preferredLaunchStackId, topStack);
    } else if (mSourceRecord != null) {
        result = setTaskFromSourceRecord();
    } else if (mInTask != null) {
        result = setTaskFromInTask();
    } else {
        setTaskToCurrentTopOrCreateNewTask();
    }
    ...
    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition, mOptions);
    if (mDoResume) {
        final ActivityRecord topTaskActivity = mStartActivity.getTask().topRunningActivityLocked();
        if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) {
            ...
        } else {
            if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityUnchecked");
            }
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions);
        }
    } else {
        mTargetStack.addRecentActivityLocked(mStartActivity);
    }
    ...
}

  startActivityUnchecked方法里面主要是一些栈管理的相关逻辑。启动根Activity时,会将IntentFLAG设置为FLAG_ACTIVITY_NEW_TASK,那么就满足条件调用setTaskFromReuseOrCreateNewTask方法,该方法会创建一个新的Activity任务栈。之后继续向下调用方法mSupervisor.resumeFocusedStackTopActivityLocked

(frameworks/base/core/java/android/server/am/ActivityStackSupervisor.java)

boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    ...
    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }

    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    if (r == null || r.state != RESUMED) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    } else if (r.state == RESUMED) {
        mFocusedStack.executeAppTransition(targetOptions);
    }
    return false;
}

  首先调用ActivityStacktopRunningActivityLocked的获取要启动的Activity所在栈的栈顶的非停止状态的ActivityRecord。如果该ActivityRecord为空或不处于RESUMED状态,则会调用ActivityStackresumeTopActivityUncheckedLocked方法。对于即将要启动的Activity来说,此处判断必定满足。下面就继续跟踪调用resumeTopActivityUncheckedLocked方法。

(frameworks/base/core/java/android/server/am/ActivityStack.java)

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    ...
    boolean result = false;
    try {
        mStackSupervisor.inResumeTopActivity = true;
        result = resumeTopActivityInnerLocked(prev, options);
    } finally {
        mStackSupervisor.inResumeTopActivity = false;
    }
    //  
    final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
    if (next == null || !next.canTurnScreenOn()) {
        checkReadyForSleep();
    }
    return result;
}

  该方法是为了确保栈顶Activity是已恢复的。紧接着跟踪resumeTopActivityInnerLocked方法。

(frameworks/base/core/java/android/server/am/ActivityStack.java)

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    ...
    mStackSupervisor.startSpecificActivityLocked(next, true, true);
    ...
}

  该方法内的代码非常多,但最终会执行mStackSupervisor.startSpecificActivityLocked方法。该方法如下。

(frameworks/base/core/java/android/server/am/ActivityStackSupervisor.java)

void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
    ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true);

    r.getStack().setLaunchTime(r);

    if (app != null && app.thread != null) {
        try {
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) {
                app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, mService.mProcessStats);
            }
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
        }
    }

    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true);
}

  首先获取到需要启动的Activity的应用进程,判断该进程是否运行。如果进程运行,则会执行realStartActivityLocked方法。

(frameworks/base/core/java/android/server/am/ActivityStackSupervisor.java)

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {
    ...
    app.thread.scheduleLauchActivity(new Intent(r.intent), r.appToken,
                        System.identityHashCode(r), r.info,
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, !andResume,
                        mService.isNextTransitionForward(), profilerInfo);
    ...
}

  这里的app表示要启动的Activity所在的进程。app.threadIApplicationThread类型,是AIDL文件,那么继续寻找,发现AcitvityThread的内部类ApplicationThread实现了IApplicationThread.Stub

(frameworks/base/core/java/android/app/AcitivtyThread.java)

private class ApplicationThread extends IApplicationThread.Stub {
    ...
    @Override
    public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
            CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
            int procState, Bundle state, PersistableBundle persistentState,
            List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
            boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
        updateProcessState(procState, false);

        ActivityClientRecord r = new ActivityClientRecord();
        ...
        sendMessage(H.LAUNCH_ACTIVITY, r);
    }
    ...
}

  这里调用了ActivityThread类内的sendMessage方法。该方法最终调用了内部Handler子类HhandleMessage方法。

(frameworks/base/core/java/android/app/AcitivtyThread.java)

private class H extends Handler {
    ...
    public void handleMessage(Message msg) {
        ...
        switch (msg.what) {
            case LAUNCH_ACTIVITY: {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
            final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

            r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);
            handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            } break;
            ...
        }
        ...
    }
    ...
}

  这里调用了ActivityThreadhandleLaunchActivity方法。

(frameworks/base/core/java/android/app/AcitivtyThread.java)

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    ...
    Activity a = performLaunchActivity(r, customIntent);
    if (a != null) {
        ...
        handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
        ...
    }
    ...
}

  该方法内调用了performLaunchActivity方法,是启动Activity的核心方法。

(frameworks/base/core/java/android/app/AcitivtyThread.java)

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ...
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
        ...
    } catch (Exception e) {
        ...
    }
    try {
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        ...
        if (activity != null) {
            ...
            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);
            ...
            // 调用Activity的performCreate方法
            // 而performCreate方法则会调用onCreate方法
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            ...
            if (!r.activity.mFinished) {
                // 此处经过一系列调用,最终会调用onStart方法
                activity.performStart();
                r.stopped = false;
            }
            ...
        }
        ...
        mActivities.put(r.token, r);
    } catch (Exception e) {
        ...
    }
    return activity;
}

  在第一处注释处,该方法经过Instrumenation调用了ActivityonCreate方法。在第二处注释处,该方法又经过一系列调用,最终调用了ActivityonStart方法。到此,我们终于看到了常用的熟悉方法。
  

总结

  将上面一整套流程总结后,我们可以得到如下图所示的调用链。
启动方法调用链
  总的来说,Activity的启动流程可以分为在两个进程内处理,以及进程之间互相通信完成的。
  当然,本篇文章仅仅是讲解了方法的调用链,并简单的说明了一下一些重要方法的作用,讲解的比较粗浅。我会在后续的文章中,更加深入的分析Android源码。

发布了21 篇原创文章 · 获赞 63 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/dongzhong1990/article/details/80163897