Android程序员都该明白--从Activity到View(一)

每一个有理想的Android程序员都该自己去看一遍谷歌大神写的View机制的相关源码,这个是进阶必不可少的一步。
而View的初始化又是和Activity 关联在一起的,这也好理解毕竟Activity 是View的容器嘛。
在这里我就不说Activity的组成了,这个部分网上教程很多,大致也可以用这张图表示:这里写图片描述

我们写的布局文件XML文件一般放在ContentView 里面,所以ContentView才是我们所有布局的最上层的跟布局。这回我们只探究一个Activity 启动的过程。

Activity 启动—- 创建一个Activity

启动一个Activity 使用StartActivity ()方法,这个方法有很多重载机制,但是他们最终还是调用startActivityForResult这个方法这里贴出主要代码

 public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
        //因为我们启动的Activity上面没有父类的Activity所以 mParent 这个值是空
            options = transferSpringboardActivityOptions(options);
            //得到一个Activty的执行结果 
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
             //无关代码,ar一般返回null 。
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);

        }
        //其他无关代码2.0一下的Android系统才会跑,那个时候你创建的Activity 的顶部还有一个Activity、
    }

在这里可以看到有个execStartActivity 的方法,是这个方法进行执行开始逻辑,并返回一个Activity结果给这个方法,一般返回的都是null ,在先看execStartActivity 这个方法:

  public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        Uri referrer = target != null ? target.onProvideReferrer() : null;
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        //.....去除无关代码,mActivityMonitors 创建的时候等于空
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManagerNative.getDefault()
                .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;
    }

这里发现他的返回值是null,但是其中会执行ActivityManagerNative.getDefault()
.startActivity这个方法,并且传入了intent 从名字上看这个是Activity的管理类,所以应该就是在这个里面进行创建一个Activity出来的。 首先我们看下ActivityManagerNative 这个类结构:

    public abstract class ActivityManagerNative extends Binder implements IActivityManager

说明他是一个跨进程的东西,所以创建一个Activity并不是在自己的进程里面创建的,而是通过Binder的方式进行跨进程创建的。感觉上是一种AIDL的通信方式,也不知道对不对。找到这个的startActivty ,发现他最后通过跨进程的方式调到ActivityStackSuperisor startAtivityMayWait()方法里面, 之后又调到了startActivityLocked-》startActivityUncheckedLocked ->ActivityStack的resumeTopActivitiesLocked,大致调度图如下:
Android开发艺术
最后调用的realStartActivityLocked 里面会调用app.thread.scheduleLaunchActivity这个方法,app.thread是的类型是IApplicationThread 这个接口,这个接口定义了一批启动停止Activity的方法,而他的实现却是ActivityThread的内部类ApplicationThread,这个内部类继承了ActivityManagerNative

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值