美文网首页
Activity的启动过程

Activity的启动过程

作者: dream0915 | 来源:发表于2017-09-26 10:42 被阅读0次

    这篇文章我们来介绍Activity的工作过程.

    images.png

    首先,如果我们要启动一个Activity,会调用Activity的startActivity方法.

    2.png 1.png 3.png

    这里只是罗列了几个重载的方法.但是不难发现,这些重载方法都调用了一个startActivityForResult方法.

    那么而我们研究一下startActivityForResult方法

    4.png

    哦哦,忘记说了,我们看代码切记不要抓着细节不放,一行两行代码代表不了什么,但是过于抓细节会让我们看代码云里雾里,形成一种只见树木不见森林的状态.我们讲求对整体流程的把握.

    在startActivityForResult这个方法里面.我们只把握mParent==null的部分. 对于这个mParent,在API13之前,是一个ActivityGroup,即一个可以装多个Activity的容器.在API13之后,就变成了Fragment.

    细看startActivityForResult的函数体,我们发现它调用到了 mInstrumentation.execStartActivity(this,mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);

    这个mInstrumentation是什么呢?其实就是大名鼎鼎的Instrumentation类.这个类在启动App,启动Activity中起到非常重要的作用.在之后我们可以看到, Instrumentation也是一个非常重要的帮助类.

    个人比较喜欢看一个函数的参数,分析他们的意义.
    mInstrumentation.execStartActivity(
    this, 当前的Activity
    mMainThread.getApplicationThread(), 这个参数得到的结果是ApplicationThread对象
    mToken, 这是一个IBinder对象
    this, 当前的Activity
    intent, 调用startActivity启动的 intent.
    requestCode, 请求码
    options 可能为空的值
    );

    7a9f84f84a774bde89f1d43d7ada8877.jpeg

    接下里我们跟到mInstrumentation.execStartActivity方法

    5.png

    仔细看下函数声明
    public ActivityResult execStartActivity(
    Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options)

    再结合第一行代码
    IApplicationThread whoThread = (IApplicationThread) contextThread;

    我们发现上文中传入的mMainThread.getApplicationThread()参数,既是一个IBinder参数,又是一个IApplicationThread参数.我们可以猜测他们的关系.可能IApplicationThread是IBinder接口(IInteface)的子类.而ApplicationThread 和 IApplicationThread也是父子关系.

    我们简单看下一下IApplicationThread的内容.我们发现其中大量的Activity的启动停止接口(其实还有service的)


    6.png

    到此为止...

    回到execStartActivity函数内部.

    我们发现关键代码
    int result = ActivityManagerNative.getDefault() .startActivity(
    whoThread,
    who.getBasePackageName(),
    intent,
    intent.resolveTypeIfNeeded(who.getContentResolver()),
    token, target != null ? target.mEmbeddedID : null,
    requestCode,
    0,
    null,
    options);

    重点是ActivityManagerNative.getDefault()到底是什么鬼...

    其实答案是确定的.是一个AMS(来,跟我读,ActivityManagerService)对象.这个AMS是运行在另外一个进程的当中的.我们通过Binder机制来进行进程间的通信.

    具体的继承关系是这样的

    Binder.png

    所以我们的得到是一个AMS对象.随后我们转到AMS的startActivity方法


    image.png

    一步一步跟,发现调用到了ActivityStackSupervisor的startActivityMayWait方法.

    接下来我们画个步骤图:

    startActivityMayWait-->startActivityLocked-->startActivityUncheckedLocked-->resumeTopActivitiesLocked-->resumeTopActivityLocked(ActivityStack)-->resumeTopActivityLocked(ActivityStack)-->resumeTopActivityLocked-->resumeTopActivityInnerLocked-->startSpecificActivityLocked-->realStartActivityLocked-->app.thread.scheduleLaunchActivity

    app.thread是一个IApplicationThread.最终还是转到了IApplicationThread的scheduleLaunchActivity.
    ApplicationThread也是ActivityThread的一个内部类.
    而他们之间的继承关系是:ApplicationThread是IApplicationThread的儿子....

    那么我们去看ApplicationThread好了.

    7.png

    这个发现它发送了一个信息给H

    H是什么呢??


    8.png

    其实就是一个Handler来处理启动Activity的过程.

    9.png

    我们可以看到在handleMessage里面处理启动Activity的方法是handleLaunchActivity

    依然可以跟进去:


    9.png

    主要是performLaunchActivity方法.我们可以一步一步看


    10.png

    红色是我的标注

    到此onCreate方法被执行了...

    文章结束了....

    相关文章

      网友评论

          本文标题:Activity的启动过程

          本文链接:https://www.haomeiwen.com/subject/gkqsextx.html