android 面试Activity启动流程

android 面试题之Activity的启动流程

面试中高级的时候,很多公司都会问对Activity的启动流程了解吗?这时候内心真是一万只草泥马奔腾而过,都没准备说啥啊!市场上对Activity启动这块分析的文章很多,但是面试过程中简短的描述就需要很熟悉源码并且用精炼的语言描述出来。先看下大佬是怎么回答这个问题的:

Activity的启动过程,我们可以从Context的startActivity说起,其实现是ContextImpl的startActivity,然后内部会通过Instrumentation来尝试启动Activity,这是一个跨进程过程,它会调用ams的startActivity方法,当ams校验完activity的合法性后,会通过ApplicationThread回调到我们的进程,这也是一次跨进程过程,而applicationThread就是一个binder,回调逻辑是在binder线程池中完成的,所以需要通过Handler H将其切换到ui线程,第一个消息是LAUNCH_ACTIVITY,它对应handleLaunchActivity,在这个方法里完成了Activity的创建和启动,接着,在activity的onResume中,activity的内容将开始渲染到window上,然后开始绘制直到我们看见。——任玉刚大佬

详细分析如下

当我们在activity中调用startActivity方法来开启一个Activity的时候,调用流程如下:
startActivity—->startActivity(intent,bundle)–>startActivityForResult(intent,-1,bundle)
调用到startActivityForResult的时候,具体方法是:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

这里会先判断mParent是否为Null,mParent的意思是父类Activity,刚开始进来的mParent是为null的,所以后边开始调用
Instumentation.execStartActivity。
当我们使用Context.startActivity的时候,最后也是调用mMainThread.getInstrumentation().execStartActivity方法
那么Instrumentation有什么用呢?为何要在Instrumentation中去执行execStartActivity方法?
Instrumentation是在任何应用程序运行前进行初始化的,可以用它来检测系统和应用程序间的交互。每一个activity都会
持有instrumentation的引用,但是整个进程只有一个instrumentation实例,instrumentation相当于一个大管家,管理着
activity和application的生命周期,包括activity的创建。

现在我们来看看Intrumentation的execStartActivity方法。

    public ActivityResult execStartActivity(Context who,IBinder contextThread,IBinder token,Activity target,Intent intent,int requestCode,bundle options){
       ...
       ActivityManagerNative.getService().startActivity();
          }
context who:activity所在的上下文
IBinder contextThread:上下文所在的主线程
IBinder token:启动的activity的标识
Activity target:被启动的activity
Intent intent:传入的intent
int requestCode:请求码
bundle options:额外的参数

那么Instrumentation是如何创建activity以及执行activity的生命周期方法的呢?是谁传递过来的信息?
是ActivityThread。通过ActivityThread来告诉Instrumentation来执行activity的生命周期方法以及创建activity,那么
ActivityThread又是那个类通知的呢?是AMS。
AMS通过Binder通信告诉ActivityThread,该创建一个新的Activity了,那么ActivityThread则会调用Instrumentation来
创建一个Activity。
好,我们接着上边的ActivityManagerNative.getDefault()来讲,这个getDefault方法返回的是什么呢?返回的是ActivityManagerService的
远程接口,也就是ActivityManagerProxy。再看ActivityManagerProxy.startActivity则就是利用Binder进行通信,把所有的参数数据封装在Parcel
对象里,然后通过binder对象的transact方法传输到AMS。
ActivityManagerProxy(客户端)====>Binder驱动(中转站)====>ActivityManagerService(服务端) (Binder是单向通信的)

到此就是Activity创建传递到AMS的一个过程,后边就是ActivityManagerService拿到数据和标识之后开始做一些合法性验证
然后再利用Binder进行通信告诉(?告诉那个类)来做创建

AMS接收到客户端请求之后,会如何创建一个Activity?如何回调到应用层并切换到H上呢?
下次再分解,也可以参考下边的链接

https://blog.csdn.net/zhaokaiqiang1992/article/details/49428287

https://www.jianshu.com/p/8a8ec5c17495

你可能感兴趣的:(android上市公司面试)