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

来源:互联网 发布:centos 生成uuid 编辑:程序博客网 时间:2024/06/03 18:26

每一个有理想的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