Activity的启动过程

Activity的启动过程很复杂,反复看了几遍源码,感觉是记住了记牢了,但是过几天之后肯定忘,因此写写博客,加深记忆,也便于自己以后复习巩固。
我们启动一个Activity的时候都是从startActivity方法开始的,我们就从这里入手往里面找。(下面是类的方法的依次调用顺序)
1、【Activity】(startActivity)

2、【Activity】(startActivityForResult)

3、【Instrumentation】(execStartActivity)

4、【ActivityManagerNative (getDefault)】(startActivity)

5、【ActivityManagerService】(startActivity)

6、【ActivityStackSupervisor】(startActivityMayWait)

7、【ActivityStackSupervisor】(startActivityLocked)

8、【ActivityStackSupervisor】(startActivityUncheckedLocked)

9、【ActivityStackSupervisor】(resumeTopActivitiesLocked)

10、【ActivityStack】(resumeTopActivityLocked)

11、【ActivityStack】(resumeTopActivityInnerLocked)

12、【ActivityStackSupervisor】(startSpecificActivityLocked)

13、【ActivityStackSupervisor】(realStartActivityLocked)

14、【ProcessRecord. IApplicationThread】(scheduleLaunchActivity)——-》app.thread.scheduleLaunchActivity

15、【ApplicationThread】(scheduleLaunchActivity)

16、【ActivityThread】(handleLaunchActivity)

17、【ActivityThread】(performLaunchActivity)

上面这些方法并不是囊括了所有的方法,只是列出了能显示出主体流程的一些方法。前面加了序号只是为了一会解释某个类或者方法的时候方便定位。
之前一直听说Activity的启动是从ActivityThread的performLaunchActivity方法开始的,没想到中间竟然经历了这么复杂的调用过程。
先来说一说上面的4、5、两步。

ActivityManagerNative.getDefault()方法。 返回的是IActivityManager类型。而IActivityManager是一个接口,其实ActivityManagerService就是它的实现类

ActivityManagerService继承了ActivityManagerNative,ActivityManagerNative继承了Binder,实现了IActivityManager接口, IActivityManager接口继承了IInterface接口

其实AMS是一个Binder。Binder是实现进程间通信的一个重要类。

再看看14、15两步。

app.thread.scheduleLaunchActivity

app是ProcessRecord类的实例,thread是IApplicationThread对象。IApplicationThread是一个接口,继承了IInterface接口,IApplicationThread的具体实现是ApplicationThread。

ApplicationThread继承了ApplicationThreadNative,ApplicationThreadNative也继承了Binder实现了IApplicationThread接口,IApplicationThread接口继承了IInterface接口,这个过程跟上面的AMS很相似。

ApplicationThread是ActivityThread的一个内部类。从ApplicationThread的scheduleLaunchActivity方法是怎么传递到ActivityThread的handleLaunchActivity方法的呢?

是Handler发消息,发了一个Message.what = LAUNCH_ACTIVITY的消息,找到Handler的handlemessage方法,发现调用了【ActivityThread】(handleLaunchActivity)方法。

接下来在看看最主要的【ActivityThread】(performLaunchActivity)方法是怎么实现了Activity的启动的。

在ActivityThread的performLaunchActivity方法里主要干了下面几件事

*【Instrumentation】(newActivity) —通过这个方法使用类加载器创建了Activity

Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            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);
            }
        }

Instrumentation的newActivity方法就几行代码

public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
    }

*【LoadedApk】(makeApplication)—通过这个方法使用类加载器来尝试创建Application对象

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

LoadedApk的makeApplication方法源码

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }

        Application app = null;

        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                initializeJavaContextClassLoader();
            }
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            if (!mActivityThread.mInstrumentation.onException(app, e)) {
                throw new RuntimeException(
                    "Unable to instantiate application " + appClass
                    + ": " + e.toString(), e);
            }
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;

        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!instrumentation.onException(app, e)) {
                    throw new RuntimeException(
                        "Unable to create application " + app.getClass().getName()
                        + ": " + e.toString(), e);
                }
            }
        }

        // Rewrite the R 'constants' for all library apks.
        SparseArray<String> packageIdentifiers = getAssets(mActivityThread)
                .getAssignedPackageIdentifiers();
        final int N = packageIdentifiers.size();
        for (int i = 0; i < N; i++) {
            final int id = packageIdentifiers.keyAt(i);
            if (id == 0x01 || id == 0x7f) {
                continue;
            }

            rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
        }

        return app;
    }

可以看出最后是调用了【Instrumentation】(newApplication) 方法 源码如下 也是用了类加载器 跟Activity的类似

 static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }

* 创建ContextImpl 并调用Activity的attach方法 来完成一些重要数据的初始化

Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                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);

* 接下来通过【Instrumentation】(callActivityOnCreate)方法来调用了Activity的onCreate方法。

到这里算是完成了Activity的启动过程。

mInstrumentation.callActivityOnCreate(activity, r.state);
public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }
final void performCreate(Bundle icicle) {
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

写到这里感觉有点多有点乱了,先冷静一下。。。

梳理一下,整片写到这里最后就是在【ActivityThread】(performLaunchActivity)方法里创建了Activity,Application,调用了Application的onCreate方法,调用了Activity的onCreate方法。然而Activity的生命周期不只是一个onCreate方法,还有onResume和onStart方法呢?
我们再回退到上面的第16步,在【ActivityThread】(handleLaunchActivity)这个方法里面除了调用(performLaunchActivity)这个方法,接着往下看还调用了(handleResumeActivity)方法,源码贴出来看一下:

Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);

接着看handleResumeActivity方法,里面调用了performResumeActivity

ActivityClientRecord r = performResumeActivity(token, clearHide);

在performResumeActivity方法里

r.activity.performResume();

到此调用了【Activity】(performResume)方法 看部分源码:

final void performResume() {
        performRestart();

        mFragments.execPendingActions();

        mLastNonConfigurationInstances = null;

        mCalled = false;
        // mResumed is set by the instrumentation
        mInstrumentation.callActivityOnResume(this);
        。。。。。。

在上面代码的第一行performRestart方法里会先后调用Activity的onRestart和onstart方法。
看最后一行调用了【Instrumentation】(callActivityOnResume)方法
会调用activity的onResume方法。
Activity的启动过程到此结束了。

在整个流程顺下来以后发现了一个很有意思的事情就是【Instrumentation】这个类。在调用Activity生命周期的时候都会调用到【Instrumentation】的callActivityOnXXX方法。Instrumentation类里含有大量callActivity开头的方法。截图给大家看一下
这里写图片描述

比如我们看一下上面的callActivityResume方法里面会调用activity的onResume方法,callActivityOnRestart方法里面会调用activity的onRestart方法。callActivityOnStart方法里面会调用activity的onStart方法。

好了终于写完了,不知道有没有错误的地方,如果有错误希望大家留言指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值