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 开发艺术探索》


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

查看所有标签

猜你喜欢:

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

Ruby on Rails实践之路

Ruby on Rails实践之路

沃哈 / 科学 / 2010-5 / 48.00元

《Ruby on Rails实践之路:写给PHP和Java开发者的书》内容简介:Ruby on Rails是基于MVC模式的Web框架,用于开发基于数据库的Web应用。Ruby on Rails中内含了所需的Web服务器WEBrick。该框架配置的数据库除了缺省的MySQL外,还可以是Oracle、SQL Server等其他数据库。《Ruby on Rails实践之路:写给PHP和Java开发者的......一起来看看 《Ruby on Rails实践之路》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器