从源码角度看Activity生命周期

简介

Activity是几乎所有初级安卓程序员必学的一个知识点。我们都知道安卓最大的特色就是它能够呈现给用户界面,使用户能够与应用程序交互,这其中最重要的基本类就是各个Activity。然而,很多安卓开发者以为自己熟知了Activity的生命周期与launchMode等等知识点,就以为自己理解了它们。然而事实上并不,安卓源码中潜藏着十分复杂的逻辑支撑着Activity生命周期的变化。

本篇文章中,我将以源码的视角,分析Activity的每个生命周期的回调是如何被调用到的。同时,一些安卓framework的基本知识也会详细的讲讲。文章最后会留下几个有意义的问题,很值得我们去理解。

整体图

这张图虽然长的很像谷歌官方的那张图,但是的确是我自己画出来了的,和官方的图还是不太一样的。这里面的每个生命周期回调都会在下面的文章中分析到。

onCreate & onStart

启动一个Activity是整个生命周期最复杂的部分,这块老罗的书中就专门用了一章去讲。但我觉着我还是很有必要再用自己的语言去分析一遍,我认为就算看过老罗的那篇关于Activity的文章,再看我写的也是会有不少收获的~

App端调用

ContextImpl.java

@Override
public void startActivity(Intent intent, Bundle options) {
...
    // 先获取到Instrumentation实例
    // Instrumentation实例是在当前进程调用attach后,在bindApplication时初始化的
    mMainThread.getInstrumentation().execStartActivity(
            getOuterContext(), mMainThread.getApplicationThread(), null,
            (Activity) null, intent, -1, options);
}

关于ActivityThread的Instrumentation对象初始化,这方面以后我会单独写一篇在进程启动后,应用是如何绑定Application并初始化的分析。进程启动的源码分析,请看我的另一篇博客: 从源码角度看AMS.startProcessLocked

安卓中的双向bind call通信

Instrumentation.java

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    // 获取到ApplicationThread binder call句柄,AMS调用调用它来通知ActivityThread onCreate服务端操作已经完成
    IApplicationThread whoThread = (IApplicationThread) contextThread;
...
    try {
        ...
            // 获取与AMS binder call 通信的代理对象
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
...
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

安卓AMS核心组件中,最重要的两个binder接口当属IActivityManager和IApplicationThread了,App应用四大组件与AMS服务的双向通信基本仰仗着它们,以下作了个图方便理解:

main binder interface

main binder interface

  • ActivityManagerService继承自ActivityManagerNative, 为所有应用提供组件的服务;所有应用依靠ActivityManagerProxy代理对象调用接口
  • ApplicationThread是ActivityThread中一个内部类,它直接继承了ApplicationThreadNative对象,某种意义上来说是AMS的服务端。当AMS执行完操作时,依靠调用ApplicationThreadProxy的代理对象方法来通知应用完成余下的操作。

这样的设计在安卓系统中很通用,有一点需要额外留意的,大部分App调用到system_server端的接口是非ONEWAY的,也就是同步调用,应用需要等待system_server执行完成。大部分system_server调用到App端的接口是ONEWAY的,也就是异步调用,system_server的服务不需要等待应用完成操作。这样的设计保证了system_server不会收到App处理快慢的影响。

我个人认为,这样的设计其实是有弊端的。例如,如果system_server的某个服务接口调用耗时过久,并且持有了十分紧缺的AMS锁或者说PMS锁,那么其它调用很有可能需要等待这个锁。这样就导致了其它应用的调用等待时间长短会受到系统状况的影响。如果这个应用是前台应用,很有可能会导致ANR,直接影响到用户的使用体验。

因为这块实在是基础,所以谈的比较多。我们继续看Activity.onCreate的调用...

system_server端调用

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 options, int userId) {
...
    return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null, null, options, false, userId, null, null);
}

ActivityStackSupervisor.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 config,
        Bundle options, boolean ignoreTargetSecurity, int userId,
        IActivityContainer iContainer, TaskRecord inTask) {
...
    // 从manifesst中获取Actiivty信息
    // 这块需要调用到PMS的接口,关于PMS如何读取与解析manifest的中信息,后续会再进行分析
    ActivityInfo aInfo =
            resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
...
    synchronized (mService) {
...
        int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                voiceSession, voiceInteractor, resultTo, resultWho,
                requestCode, callingPid, callingUid, callingPackage,
                realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
                componentSpecified, null, container, inTask);
...

        return res;
    }
}

final int startActivityLocked(IApplicationThread caller,
        Intent intent, String resolvedType, ActivityInfo aInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode,
        int callingPid, int callingUid, String callingPackage,
        int realCallingPid, int realCallingUid, int startFlags, Bundle options,
        boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
        ActivityContainer container, TaskRecord inTask) {
...
    // 创建一个ActivityRecord
    // AMS中,还存在着BroadcastRecord, ProcessRecord, ServiceRecord这些类,用于表示单个的组件记录
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
            intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
            requestCode, componentSpecified, voiceSession != null, this, container, options);
...

    err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
            startFlags, true, options, inTask);
...
    return err;
}
final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
        boolean doResume, Bundle options, TaskRecord inTask) {
...
     // 涉及到launchMode的逻辑
    final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
    final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
    final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
...
    targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
...
    return ActivityManager.START_SUCCESS;
}

这块的代码段其实特别长,涉及到stack的切换,还是挺复杂的。这块以后专门写一篇文章分析Activity launchMode机制。

ActivityStack.java

final void startActivityLocked(ActivityRecord r, boolean newTask,
        boolean doResume, boolean keepCurTransition, Bundle options) {
...
    task.addActivityToTop(r);
    task.setFrontOfTask();

    r.putInHistory();
if (!isHomeStack() || numActivities() > 0) {
...
        mWindowManager.addAppToken(task.mActivities.indexOf(r),
                r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
                r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
...
        if (r.mLaunchTaskBehind) {
            // Don't do a starting window for mLaunchTaskBehind. More importantly make sure we
            // tell WindowManager that r is visible even though it is at the back of the stack.
            mWindowManager.setAppVisibility(r.appToken, true);
            ensureActivitiesVisibleLocked(null, 0);
        } else if (SHOW_APP_STARTING_PREVIEW && doShow) {
...
            mWindowManager.setAppStartingWindow(
                    r.appToken, r.packageName, r.theme,
                    mService.compatibilityInfoForPackageLocked(
                            r.info.applicationInfo), r.nonLocalizedLabel,
                    r.labelRes, r.icon, r.logo, r.windowFlags,
                    prev != null ? prev.appToken : null, showStartingIcon);
            r.mStartingWindowShown = true;
        }
    } else {
        // If this is the first activity, don't do any fancy animations,
        // because there is nothing for it to animate on top of.
        mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                (r.info.flags & ActivityInfo.FLAG_SHOW_FOR_ALL_USERS) != 0, r.userId,
                r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind);
...
    }
...

    if (doResume) {
        mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
    }
}

以上代码涉及到window apptoken, TaskRecord的操作,详细看的话篇幅很大,先略过...

ActivityStackSupervisor.java

boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
        Bundle targetOptions) {
...
    if (isFrontStack(targetStack)) {
        // 将当前ActivityStack置顶
        result = targetStack.resumeTopActivityLocked(target, targetOptions);
    }
...
    return result;
}

ActivityStack.java

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
...
    try {
...
        result = resumeTopActivityInnerLocked(prev, options);
    }
...
    return result;
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
...
    // Find the first activity that is not finishing.
    final ActivityRecord next = topRunningActivityLocked(null);
...
    final TaskRecord prevTask = prev != null ? prev.task : null;
    if (next == null) {
...
         // 这里涉及到回到桌面的逻辑...
        return isOnHomeDisplay() &&
                mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
    }
...
    ActivityStack lastStack = mStackSupervisor.getLastStack();
    if (next.app != null && next.app.thread != null) {
...
    } else {
        // Whoops, need to restart this activity!
        if (!next.hasBeenLaunched) {
            next.hasBeenLaunched = true;
        } else {
...
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
...
    return true;
}

ActivityStackSupervisor.java

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);
...
    if (app != null && app.thread != null) {
        try {
...
              // 先前的服务端操作已经完成,且应用进程已经存在,开始启动Activity
            realStartActivityLocked(r, app, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
...
    }

    // 如果Activity所在进程未启动,则会先创建进程,再启动这个Activity
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

此处,如果Activity所在进程不存在,则会先创建进程,然后再绑定Application,最后启动这个Activity

final boolean realStartActivityLocked(ActivityRecord r,
        ProcessRecord app, boolean andResume, boolean checkConfig)
        throws RemoteException {
...
     // 更新进程的优先级
    mService.updateLruProcessLocked(app, true, null);
    mService.updateOomAdjLocked();
...
    final ActivityStack stack = task.stack;
    try {
...
        app.forceProcessStateUpTo(mService.mTopProcessState);
        // binder call 回到客户端
        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
                task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
...
    } catch (RemoteException e) {
...
    }
...
    return true;
}

到这里,Activity的创建在服务端就完成了,现在就是调用到客户端完成Activity的onCreate生命周期调用

ActivityThread.java

@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) {
...
    sendMessage(H.LAUNCH_ACTIVITY, r);
}

public void handleMessage(Message msg) {
...
        case RELAUNCH_ACTIVITY: {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
            ActivityClientRecord r = (ActivityClientRecord)msg.obj;
            handleRelaunchActivity(r);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        } break;
}

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...å
    // Initialize before creating the activity
    WindowManagerGlobal.initialize();

    Activity a = performLaunchActivity(r, customIntent);
...
}

在ActivityThread中,维护着一个名为H的Handler类,它会往主线程的消息队列中抛入事件。当system_server binder call到App端时,App的Binder线程并不会直接去做各种操作,而是向主线程队列中sendMessage,排队等待事件的派发。

```java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
...
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
// 反射创建Activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
} catch (Exception e) {
...
}
...

try {
    // 获取Application实例
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);

...
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
...
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);

...
activity.mCalled = false;
// 此处调用Activity.onCreate方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
if (!r.activity.mFinished) {
// 这里调用Activity.onStart方法
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
// 这里调用Activity.onRestroeInstanceState方法
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
// 调用Activity.onPostCreate方法
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
...
}
}
...
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {

top Created with Sketch.