6

我已经阅读了标准的 Windows 相关文档并浏览了一堆源代码,试图了解 Android Windows 的创建方式和时间。我相信我已经拥护它,并希望对其进行验证或更正。

据我所知,只有两种方法可以获取 Window 对象的句柄。

1. Activity's getWindow.
2. Dialog's getWindow method.

在上述两种情况下,您都可以使用 getWindow 获取 Window 的句柄,然后使用该句柄操作 Window。

Windows 也可以通过使用 WindowManager 的 addView 方法来创建,但无法获得此类 Windows 的句柄。这是一个非常令人困惑的领域,因为 addView 方法本身并不意味着创建一个窗口,甚至视图管理器源代码中的注释也只是说明了以下内容。

Assign the passed LayoutParams to the passed View and add the view to
the window.

因此,该方法似乎意味着将视图添加到现有窗口。然而, addView 的第二个参数是一个 WindowManager.LayoutParams 实例,除其他外,它指定了一个窗口类型(例如,TYPE_SYSTEM_ALERT),这意味着实际上正在创建一个窗口。事实上,情况就是这样。这是源代码中发生的事情的非常简短的概述。(对于新手:您可以在许多不同的网站上浏览源代码;我最喜欢的是http://grepcode.com。)

  1. WindowManager 实现了 ViewManager 接口,这是定义 addView 的地方。网址: http: //grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/view/ViewManager.java#ViewManager.addView%28android.view。查看%2Candroid.view.ViewGroup.LayoutParams%29

  2. WindowManager 类的实际实现称为 WindowManagerImpl。它的addView 调用WindowManagerGlobal 的addView。网址: http: //grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/view/WindowManagerImpl.java#83

  3. WindowManagerGlobal 的 addView 是完成真正工作的地方。网址: http: //grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/view/WindowManagerGlobal.java#WindowManagerGlobal.addView%28android.view。 View%2Candroid.view.ViewGroup.LayoutParams%2Candroid.view.Display%2Candroid.view.Window%29

    1. 验证传入的参数是 WindowManager.LayoutParams。
    2. 如果 View 有父级,则调整布局参数。
    3. 确定新视图(又名窗口)是否为面板窗口(即子窗口)并进行处理。
    4. 创建一个新的 ViewRootImpl。
    5. 将 View、ViewRootImpl 和 WindowManager.LayoutParams 实例添加到单独的 ArrayList 中。
    6. 通过后者的 setView 方法将 View 和相关参数添加到 ViewRootImpl。
  4. ViewRootImpl 的 setView 方法然后做了一堆低级的工作。它会在各种错误情况下引发“无法添加窗口...”消息的变体异常。根据 ViewRootImpl 的主要评论,它是“视图层次结构的顶部,实现 View 和 WindowManager 之间所需的协议。这在很大程度上是 WindowManagerGlobal 的内部实现细节。”

    网址: http: //grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/view/ViewRootImpl.java#ViewRootImpl.setView%28android.view。查看%2Candroid.view.WindowManager.LayoutParams%2Candroid.view.View%29

WindowManagerGlobal 似乎通过三个数组跟踪多个窗口。据我所知,ViewRootImpl 实际上是新窗口,它由 WindowManagerGlobal 管理。

综上所述,调用 addView 似乎确实创建了一个新窗口(虽然它被称为视图和窗口)但没有提供关联的 Window 类来访问它,因此开发人员不能处理它。

我的问题是:

  1. 除了上面提到的两个 getWindow 方法之外,还有其他方法可以获取 Window 实例的句柄吗?
  2. 实际上,addView 是否创建了一个 Window,如果是,有没有办法获得它的句柄?
  3. 上面还有什么不正确的吗?如果是,在哪些方面?

谢谢!巴里

4

0 回答 0