Activity的启动流程源码解析

80 阅读4分钟

startActivity(new Intent()) 最开始从startActivity()开始调用跳转到目标Activity。不管是否携带Bundle最后都会进入Activity中的startActivityForResult()中

@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中会调用Instrumentation(),Instrumentation的主要作用是提供了一种机制来运行和监视应用程序的生命周期,以及向应用程序发送各种事件,例如按键和触摸事件。

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

1、第一步调用Instrumentation.exexStartActivity()这个方法的第二个参数为mMainThread.getApplicationThread()是获取到ActivityThread()中的ApplicationThread(),这个ApplicationThread是一个Binder类,这个类最终会被传到服务端,在服务端作为客户端的代理来调用客户端的代码。

跟着mInstrumentation.exrcStartActivity()进去

//通过获取ActivityManagerService来启动Activity
int result = ActivityTaskManager.getService()
    .startActivity(whoThread, who.getBasePackageName(), intent,
            intent.resolveTypeIfNeeded(who.getContentResolver()),
            token, target != null ? target.mEmbeddedID : null,
            requestCode, 0, null, options);

ActivityManagerService的主要作用是负责和管理系统中的Activity,包括Activity的启动、调度、切换及应用进程的管理和调度等工作。它是在SystemServer的进程中创建的,并且会在SystemServer中创建一个进程给ActivityManagerService运行,创建完成后,就把它注册到ServerManager中

@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
        new Singleton<IActivityTaskManager>() {
            @Override
            protected IActivityTaskManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                return IActivityTaskManager.Stub.asInterface(b);
            }
        };

ActivityTaskManager.getService()最终会调用到上图代码,这里又涉及到跨进程的操作,上图进入到服务端进程,即上述说的SystemServer进程。

进入到SystemServer进程会会调用IApplicationThread的scheduleLaunchActivity方法,该方法会调用ApplicationThread的scheduleLaunchActivity(),该方法会调用H.handlerMessage(msg)。在ApplicationThread中会执行handlerStartActivity()和handlerResumeActivity()来执行Activity的生命周期。

Activity的创建

Activity的创建是在服务端通过添加一个LauncherActivityItem到ClientTransaction中实现的,然后通过IApplication跨进程将ClientTransaction传到客户端执行。客户端通过遍历ClientTransaction中所有的ClientTransactionItem,并执行了它的execute方法来执行Activity的创建的

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

上面的client.handleLaunchActivity()实际上是调用的是ActivityThread的handlerLaunchActivity()方法

public final class ActivityThread extends ClientTransactionHandler {
 public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
//初始化WindowManagerGlobal
WindowManagerGlobal.initialize();

// Hint the GraphicsEnvironment that an activity is launching on the process.
GraphicsEnvironment.hintActivityLaunch();
//执行Activity的创建流程
final Activity a = performLaunchActivity(r, customIntent);
}

调用performLaunchActivity()

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
//通过反射创建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);
        }
    } 

    try {
        if (activity != null) {
            //执行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,
                    r.assistToken);
            activity.mCalled = false;
        //调用Activity的onCreate()
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                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;
        }
        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;

    } 

    return activity;
}

Activity中的onResume()是通过调用ActivityThread().handleResumeActivity()来执行的,

@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
        String reason) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;

    final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
}

performResumeActivity()中先对Activity的状态进行了判断,如果状态符合,则先调用Activity的performResume(),进而执行Activity的onResume();

if (r.window == null && !a.mFinished && willBeVisible) {
    r.window = r.activity.getWindow();
    View decor = r.window.getDecorView();
    decor.setVisibility(View.INVISIBLE);
    ViewManager wm = a.getWindowManager();
    WindowManager.LayoutParams l = r.window.getAttributes();
    a.mDecor = decor;
    l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
    l.softInputMode |= forwardBit;
    if (r.mPreserveWindow) {
        a.mWindowAdded = true;
        r.mPreserveWindow = false;
        // Normally the ViewRoot sets up callbacks with the Activity
        // in addView->ViewRootImpl#setView. If we are instead reusing
        // the decor view we have to notify the view root that the
        // callbacks may have changed.
//创建viewRootImpl
        ViewRootImpl impl = decor.getViewRootImpl();
        if (impl != null) {
            impl.notifyChildRebuilt();
        }
    }
    if (a.mVisibleFromClient) {
        if (!a.mWindowAdded) {
            a.mWindowAdded = true;
            wm.addView(decor, l);
        } else {
            // The activity will get a callback for this {@link LayoutParams} change
            // earlier. However, at that time the decor will not be set (this is set
            // in this method), so no action will be taken. This call ensures the
            // callback occurs with the decor set.
            a.onWindowAttributesChanged(l);
        }
    }

执行了performResume()后接着进行执行将DecorView添加到Window中,在添加完DecorView之后创建ViewRootImpl(),在这个类中执行performTraversals()在这个方法里面会执行performMeasure(),performLayout(),performDraw(),对于view进行绘制,摆放,绘制流程。在ViewRootIml()会有一个

getRunQueue().executeActions(mAttachInfo.mHandler);
...//省略代码
performMeasure()

经常会有这个面试题,view.post()为什么可以获取到view的宽高。这个消息执行在performMeasure()之前为什么可以获取到宽高,因为这个消息队列的特性有关系,因为performTraversals()也是handler中的message(),会将上面的消息添加到这个消息执行完毕之后进行执行。所以view.post()可以获取到view的宽高。