Activity 在本地进程的创建流程,已经动画

前面几篇文章讲述了 activity在远端的创建过程,以及 Application process的创建过程。

现在接着看 activity在本地进程里面的创建流程。

上面的代码里面

在一切条件都准备完成之后,会在
ProcessRecord 里面找到 相应App 进程的远程调用thread,通过ipc 调用到
app.thread.scheduleLaunchActivity()。
执行到ActivityThread中的

    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {

   //先跳过GC。。。保证Activity顺利的创建出来
        unscheduleGcIdler();

      //设置出bitmap的DefaultDensity,Resources的config,DisplayMetrics 等config。
        handleConfigurationChanged(null, null);

        if (localLOGV) Slog.v(
            TAG, "Handling launch of " + r);

        // 获取到远端的windowmanager,以便于设置window的animation等属性
        WindowManagerGlobal.initialize();


//这个才是重点
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            Bundle oldState = r.state;

//这个就是Activity 的resume的事件来源。
//需要注意的是,fragementManager 先接受到resume事件,再是activity。
//深坑
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);

//后面的基本上就不用看了
    }

接着看 performLaunchActivity()

  private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
//略过,基本上都是在new一些基本的元素

        Activity activity = null;
        try {
//Activity 是通过系统给的classloader new 出来的。这里应该可以通过反射 去更改本地的classloader。嘿嘿,可以干一些黑科技
            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);
            }
        }
//奇怪的地方在于,activity居然是比application先new 出来,但是一定不代表着 Activity oncreate的回调是在Application的前面啊
        try {

//makeApplication 的时候,先会根据你的 apk的位置 new出一个属于自己App的 PathClassLoader,每次加载的class文件的时候,都会去
//自己的path 找属于自己的dex文件,加载相对于的class类
//然后会根据 自己的ActivityThread 和 LoadedApk data去创建一个ContextImpl,这个应该就是我们常用的ApplicationContext
//并将ApplicationContentResolver,Resources 等资源类也初始化出来
//然后就会先吊用Application中的attch 方法,将上面创建的ContextImpl 倒入到application里面来。
//然后在会吊用 application的 oncreate的方法
//在载入 apk中的R资源文件
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
            if (localLOGV) Slog.v(
                    TAG, r + ": app=" + app
                    + ", appName=" + app.getPackageName()
                    + ", pkg=" + r.packageInfo.getPackageName()
                    + ", comp=" + r.intent.getComponent().toShortString()
                    + ", dir=" + r.packageInfo.getAppDir());

            if (activity != null) {
//根据activity 在windowmanager中中注册得到的windowtoken 去创建一个带有windowtoken的 context,和上面的区别在于
//是否有权限在window层面显示,接受windowmanager的管理
                Context appContext = createBaseContextForActivity(r, activity);

//然后就是将basecontext attach上去,并且新建一个新的window。
                   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);


//在吊用oncreate之前就已经将theme属性设置了,如果重载了此方法,是不是意味在 oncreate之前能接收到回调?
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }


//终于看到了 activity oncreate的回调了,太晚了
                activity.mCalled = false;
                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.stopped = true;
//然后就是顺序执行 onstart()。
//在performStart()的时候,就会给 decorView设置listener,当画完第一贞之后,就要开始做动画,让activity做动画出来了
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
                if (!r.activity.mFinished) {
                    if (r.isPersistable()) {
                        if (r.state != null || r.persistentState != null) {
                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                    r.persistentState);
                        }
                    } else if (r.state != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                    }
                }
                if (!r.activity.mFinished) {
                    activity.mCalled = false;
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state,
                                r.persistentState);
                    } else {
                        mInstrumentation.callActivityOnPostCreate(activity, r.state);
                    }
                    if (!activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPostCreate()");
                    }
                }
            }
            r.paused = true;

            mActivities.put(r.token, r);

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }

基本上到这里acitivty 就已经启动并通过windowmanager 动画吊起来啦

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值