我已经阅读了标准的Windows相关文档,并通过一堆源代码,试图了解如何以及何时创建Android Windows.我相信我搂着它,并希望得到验证或纠正.
据我所知,只有两种方法来获取Window对象的句柄.
1. Activity's getWindow. 2. Dialog's getWindow method.
在上述两种情况下,您都可以使用getWindow获取Window的句柄,然后使用句柄操作Window.
Windows也可以通过使用WindowManager的addView方法创建,但是无法获得此类Windows的句柄.这是一个非常令人困惑的区域,因为addView方法本身并不意味着创建一个Window,甚至在View Manager源代码中对它的注释只是说明如下.
Assign the passed LayoutParams to the passed View and add the view to the window.
因此,该方法似乎意味着将View添加到现有Window.但是,addView的第二个参数是一个WindowManager.LayoutParams实例,除其他外,它指定一个Window类型(例如,TYPE_SYSTEM_ALERT),暗示实际上正在创建一个Window.事实上,情况就是如此.以下是源代码中发生的事情的简要概述.(对于新手:您可以在许多不同的网站上浏览源代码;我最喜欢的是http://grepcode.com.)
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%
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
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.查看%2Candroid.view.ViewGroup.LayoutParams%2Candroid.view.Display%2Candroid.view.Window 29%
验证传入的参数是否为WindowManager.LayoutParams.
如果View具有父级,则调整布局参数.
确定新视图(也称为窗口)是否是面板窗口(即子窗口)并处理它.
创建一个新的ViewRootImpl.
添加View,ViewRootImpl和WindowManager.LayoutParams实例以分隔ArrayLists.
通过后者的setView方法将View和关联的参数添加到ViewRootImpl.
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似乎通过三个阵列跟踪多个Windows.据我所知,ViewRootImpl实际上是新窗口,它由WindowManagerGlobal管理.
基于以上所述,看来调用addView实际上创建了一个新窗口(尽管它被不同地称为视图和窗口)但是没有提供相关的Window类来访问它,因此开发人员不能得到它的句柄.
我的问题是:
除了上面提到的两个getWindow方法之外,还有办法获取Window实例的句柄吗?
事实上,addView是否创建了一个Window,如果有的话,有没有办法获得它的句柄?
是否有其他错误,如果是,在什么方面?
谢谢!巴里