Window 的添加过程

栏目: IOS · Android · 发布时间: 5年前

内容简介:Window(或者说View) 是怎么添加到 Android 系统中然后展示给用户的?让我们来探索一下 Window 的添加过程。要探索添加的过程,必须先在源代码中找到添加 Window 的入口方法。Window 的添加需要通过 WindowManager 的

Window 的添加过程

Window(或者说View) 是怎么添加到 Android 系统中然后展示给用户的?让我们来探索一下 Window 的添加过程。

Window 添加过程的入口方法

要探索添加的过程,必须先在源代码中找到添加 Window 的入口方法。

Window 的添加需要通过 WindowManager 的 addView 方法实现,但 WindowManager 是个接口,它的真正实现类是 WindowManagerImpl 类,但 WindowManagerImpl 也并没有直接实现对 Window 的添加、删除、更新操作,而是通过桥接模式将所有操作委托给 WindowManagerGlobal 去实现。最终会调用 WindowManagerGlobal 类的 addView 方法真正开启 View 的添加过程。

所有,Window 添加过程的真正入口方法实际上是 WindowManagerGlobal 类的 addView 方法。

Window 添加过程的主要流程

WindowManagerGlobal 的 addView 方法主要分为三大步:

  1. 检查参数 params 是否是 WindowManager.LayoutParams,如果不是说明参数不合法,则会抛出异常。

    public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
        if (view == null) {
            throw new IllegalArgumentException("view must not be null");
        }
        if (display == null) {
            throw new IllegalArgumentException("display must not be null");
        }
        if (!(params instanceof WindowManager.LayoutParams)) { // 检查 params 参数是否合法
            throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
        }
        ...
    }
  2. 创建 ViewRootImpl,并将 View 添加到列表中。

    public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
            ...
            root = new ViewRootImpl(view.getContext(), display); // 创建 ViewRootImpl
            view.setLayoutParams(wparams);
            mViews.add(view); // 将View添加到mView列表中,mView 存储的是所有Window对应的View
            mRoots.add(root);
            mParams.add(wparams);
            ...
    }
  3. 通过 ViewRootImpl 的 setView 方法来添加更新界面并通过 IPC 的方式调用 WindowManagerService 的 addWindow 方法完成 Window 的添加过程。

    public void addView(View view, ViewGroup.LayoutParams params,
    Display display, Window parentWindow) {
            ...
            // do this last because it fires off messages to start doing things
            try { 
                root.setView(view, wparams, panelParentView); // ViewRootImpl的setView 方法
            } catch (RuntimeException e) {
                // BadTokenException or InvalidDisplayException, clean up.
                synchronized (mLock) {
                    final int index = findViewLocked(view, false);
                    if (index >= 0) {
                        removeViewLocked(index, true);
                    }
                }
                throw e;
            }
    }
    • ViewRootImpl 的 setView 方法是如何实现界面的更新的呢?

      setView 方法中会调用 requestLayout() 方法去完成异步刷新请求:

      @SuppressWarnings({"EmptyCatchBlock", "PointlessBooleanExpression"})
      public final class ViewRootImpl implements ViewParent,
              View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks {
          private static final String TAG = "ViewRootImpl";
          ...
          // Schedule the first layout -before- adding to the window
          // manager, to make sure we do the relayout before receiving
          // any other events from the system.
          requestLayout();           
      }

      我们再查看 requestLayout 方法的源码,看它干了什么:

      @Override
      public void requestLayout() {
          if (!mHandlingLayoutInLayoutRequest) {
               checkThread();
               mLayoutRequested = true;
               scheduleTraversals(); // scheduleTraversals 方法是View绘制的入口
          }
      }

      可以看到,是调用了 scheduleTraversals 方法进行绘制,我们知道 scheduleTraversals 是 View 执行绘制过程的入口方法,该方法会经过测量、布局、绘制这三个过程把 View 绘制出来。

    • View 绘制出来以后是怎么通过IPC调用的方式添加到 Window 中的呢?

      我们知道,WindowManager 是外界访问 Window 的入口,所以最终 WindowManager 会通过 IPC 的方式调用 WindowManagerService 的 addWindow 方法,这样一来, Window 的添加请求就交给了 WindowManagerService 来处理了,然后 WindowManagerService 会经过一系列的操作将 View 添加到 Window 中并展示出来。

      作为应用层开发者来说,了解到这个程度就差不多了,没必要去深究 WindowManagerService 的实现细节,至于 WindowManagerService 是如何处理 Window 的添加请求的,感兴趣的读者可以去查看源码。

参考书籍:

《Android 开发艺术探索》


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web Caching

Web Caching

Duane Wessels / O'Reilly Media, Inc. / 2001-6 / 39.95美元

On the World Wide Web, speed and efficiency are vital. Users have little patience for slow web pages, while network administrators want to make the most of their available bandwidth. A properly design......一起来看看 《Web Caching》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具