美文网首页
Activity Window View

Activity Window View

作者: 孤独的根号十二 | 来源:发表于2019-01-03 14:37 被阅读27次
    1_Activity加载UI-类图关系和视图结构.png

    我们知道Activity的启动过程的最后一步是调用ActivityThread的performLaunchActivity,用类加载器初始化一个activity对象

     Activity activity = null;
            try {
                ClassLoader cl = r.packageInfo.getClassLoader();
                activity = mInstrumentation.newActivity(
                        cl, component.getClassName(), r.intent);
                StrictMode.incrementExpectedActivityCount(activity.getClass());
                r.intent.setExtrasClassLoader(cl);
                r.intent.prepareToEnterProcess();
                if (r.state != null) {
                    r.state.setClassLoader(cl);
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(activity, e)) {
                    throw new RuntimeException(
                        "Unable to instantiate activity " + component
                        + ": " + e.toString(), e);
                }
            }
    

    然后调用activity的attach,初始化了mWindow对象,并进行了一系列赋值操作:

            mWindow = new PhoneWindow(this);
            mWindow.setCallback(this);
            mWindow.setOnWindowDismissedCallback(this);
            mWindow.getLayoutInflater().setPrivateFactory(this);
            if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
                mWindow.setSoftInputMode(info.softInputMode);
            }
            if (info.uiOptions != 0) {
                mWindow.setUiOptions(info.uiOptions);
            }
            mUiThread = Thread.currentThread();
    .........................省略部分代码..............................................
    
     mWindow.setWindowManager(
    (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                     mToken,mComponent.flattenToString(),
                    (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
            if (mParent != null) {
                mWindow.setContainer(mParent.getWindow());
            }
            mWindowManager = mWindow.getWindowManager();
    

    mWindo是一个Window对象,系统会创建Activity所属的Window对象并为其设置回调接口,当Window接收到外界的状态改变就会回调到Activity的方法

    接下来ActivityThread会调用handleResumeActivity:

        ActivityClientRecord r = performResumeActivity(token, clearHide);
      if (r != null) {
       final Activity a = r.activity;
        if (r.window == null && !a.mFinished && willBeVisible) {
                    r.window = r.activity.getWindow();
                    View decor = r.window.getDecorView();
                    decor.setVisibility(View.INVISIBLE);
                    ViewManager wm = a.getWindowManager();
                    WindowManager.LayoutParams l = r.window.getAttributes();
                    a.mDecor = decor;
                    l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                    l.softInputMode |= forwardBit;
                    if (a.mVisibleFromClient) {
                        a.mWindowAdded = true;
                        wm.addView(decor, l);
                    }
    

    getDecorView最后调用DecorView里面的方法generateDecor:

    protected DecorView generateDecor() {
            return new DecorView(getContext(), -1);
        }
    

    wm.addView其实调用了WindowManagerImpl的addView

     public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
            applyDefaultToken(params);
            mGlobal.addView(view, params, mDisplay, mParentWindow);
        }
    
    

    mGlobal.addView

      public void addView(View view, ViewGroup.LayoutParams params,
                            Display display, Window parentWindow) {
                           ViewRootImpl root;
    .............................省略部分代码.......................................
      root = new ViewRootImpl(view.getContext(), display);
    
      // do this last because it fires off messages to start doing things
            try {
                root.setView(view, wparams, panelParentView);
            } catch (RuntimeException e) {
                // BadTokenException or InvalidDisplayException, clean up.
                synchronized (mLock) {
                    final int index = findViewLocked(view, false);
                    if (index >= 0) {
                        removeViewLocked(index, true);
                    }
                }
    
    

    上面调用root.setView将ViewRoot和DecorView绑定在一起,ViewRootImpl的setView里面调用 requestLayout();最终调用performTraversals,进行DecorView的绘制

    View的绘制流程是从ViewRoot的performTraversals方法开始的,它经过measure,layout和draw三个过程最终将一个View绘制出来,其中measure用来测量View的宽和高,layout用来确定View在父容器中的放置位置,而draw则负责将View绘制在屏幕上。如此反复完成一棵View树的遍历,整个View视图就显示在屏幕上了。

    在onCreat()中,我们只有一个setContentView()的操作,在Activity的setContentView的实现可以看出,Activity将具体实现交给了Window处理,而Window的具体实现是PhoneWind在setContentView中创建了DecorView,DecorView是整棵View树的顶级View,然后将View添加到DecorView的mContentParent中,最后回调Activity的onContentChanged方法通知Activity视图已经发生改变。

    总结:

    Activity是整个模型的控制单元,Window属于承载模型,负责承载视图,View是视图显示模型,ActivityThread创建Activity,调用Activity的attch方法创建Window,并且设置回调,接着ActivityThread调用handleResumeActivity,取得刚才创建的Activity,调用其Window对象生成DecorView,然后将DecorView在ViewManager中和ViewRoot绑定,即ViewRoot对象持有DecorView对象,从performTraversals开始View的绘制,measureHierarchy进行组件测量

    相关文章

      网友评论

          本文标题:Activity Window View

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