View加载

    xiaoxiao2022-06-27  140

    View加载流程:

    View随着Activity的创建而加载,startActivity启动一个Activity时,在ActivityThread的 handleLaunchActivity方法中先调用Activity的attach方法初始化PhoneWindow实例, 然后会执行Activity的onCreate方法,这个时候会调用setContentView加载布局 创建出DecorView并将我们的layout加载到DecorView中,当执行到handleResumeActivity时,Activity的onResume方法被调用,然后WindowManager会将DecorView设置给ViewRootImpl。这样,DecorView就被加载到Window中了,此时界面还没有显示出来,还需要经过View的measure,layout,和 draw方法,才能完成View的工作流程。我们需要知道View的绘制是由ViewRoot来负责的,每一个DecorView都有一个与之关联的ViewRoot,这种关联关系是由WindowManager维护的,将DecorView 和 ViewRoot关联之后,ViewRootImpl的requestLayout会被调用以完成初步布局,通过scheduleTraversals方法,这个方法会执行View的measure, layout 和 draw流程。

     

    AppCompatDeleagate

    mDelegate = AppCompatDelegate.create

    mDelegate.setContentView

    AppCompatDelegateImplBase、AppCompatDelegateImplV9

    @Override

    public void setContentView(int resId){

        ensureSubDecor();

        ViewGroup contentParent = mSubDecor.findViewById(android.R.id.content);

        contentParent.removeAllViews();

        LayoutInflater.from(mContext).inflate(resId, contentParent);

        mOriginalWindowCallback.onContentChanged();

    }

     

    private ViewGroup mSubDecor;

    activity.getWindow

     

    mWindow是定义在Activity中的一个全局变量,mWindow赋值是在Activity方法中完成的。

    Window是Android里面的一个抽象类,而PhoneWindow是Window的唯一的实现类。

    PhoneWindow构造方法中很重要的一个全局变量,mDecor,这个是DecorView类的实例。那么mDecor = (DecorView) preservedWindow.getDecorView();这个方法是给DecorView赋值的。

     

    Activity在调用attach时就会初始化PhoneWindow

    mWindow = new PhoneWindow(this, window, activityConfigCallback);

    Activity的attach是在performLaunchActivity中被调用的,也就是在ActivityThread中被调用。所以在Activity中任何时候getWindow(),都能得到PhoneWindow。

     

    Activity启动流程:

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

     

     

    第一个消息:H.BIND_APPLICATION

    handleBindApplication()

    反射得到 Instrumentation

    Instrumentation会在应用程序的任何代码运行之前被实例化,可以用它来监测应用程序 和 系统的所有交互。每一个activity都会持有instrumentation的引用,但是整个进程只有一个instrumentation实例,instrumentation相当于一个大管家,管理着activity 和 application的生命周期,包括activity的创建。

    Instrumentation的execStartActivity方法

    通过ActivityThread,Instrumentation会来执行activity的生命周期方法以及创建activity,那么ActivityThread又是哪个类通知的呢???是AMS,也就是ActivityManagerService。

    AMS通过Binder通信告诉ActivityThread,该创建一个activity了,那么ActivityThread就会调用Instrumentation来创建一个activity。

    ActivityManagerNative.getDefault()返回的是ActivityManagerService的远程接口-------ActivityManagerProxy。

    ActivityManagerNative.getDefault().startActivity()则利用Binder进行通信,把所有参数数据封装在Parcel对象中,然后通过binder对象的transact方法传输到AMS。

     


    最新回复(0)