Android Windows: когда и как они создаются?
Я прочитал стандартную документацию по Windows и пролистал кучу исходного кода, пытаясь понять, как и когда создаются Android Windows. Я полагаю, что я обнимаю это и хотел бы, чтобы это было проверено или исправлено.
Насколько мне известно, есть только два способа получить дескриптор объекта Window.
1. Activity's getWindow.
2. Dialog's getWindow method.
В обоих вышеупомянутых случаях вы можете получить дескриптор окна с помощью getWindow, а затем манипулировать окном с помощью дескриптора.
Окна также могут быть созданы с помощью метода addView WindowManager, но получить дескриптор такой Windows не представляется возможным. Это очень запутанная область, потому что сам метод addView не подразумевает создание Window и даже комментарий к нему в исходном коде View Manager просто говорит следующее.
Assign the passed LayoutParams to the passed View and add the view to
the window.
Таким образом, похоже, что метод подразумевает добавление вида к существующему окну. Однако вторым параметром для addView является экземпляр WindowManager.LayoutParams, который, помимо прочего, указывает тип окна (например, TYPE_SYSTEM_ALERT), подразумевая, что окно фактически создается. Это на самом деле так. Вот очень краткое описание того, что происходит в исходном коде. (Для новичков: вы можете просматривать исходный код на многих различных веб-сайтах; мой любимый - http://grepcode.com/.)
WindowManager реализует интерфейс ViewManager, в котором определяется addView. URL: 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.View%2Candroid.view.ViewGroup.LayoutParams%29
Реальная реализация класса WindowManager называется WindowManagerImpl. Это addView вызывает addView WindowManagerGlobal. URL: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/view/WindowManagerImpl.java#83
AddView WindowManagerGlobal - то, где реальная работа сделана. URL: 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
- Проверяет, что переданные параметры являются WindowManager.LayoutParams.
- Корректирует параметры макета, если у представления есть родительский элемент.
- Определяет, является ли новый Вид (иначе Окно) панелью Окно (т.е. Подокно) или нет, и имеет дело с этим.
- Создает новый ViewRootImpl.
- Добавляет экземпляры View, ViewRootImpl и WindowManager.LayoutParams для разделения ArrayLists.
- Добавляет View и связанные параметры в ViewRootImpl с помощью последнего метода setView.
Затем метод setView в ViewRootImpl выполняет низкоуровневую работу. Он генерирует исключения с вариантами сообщений "Невозможно добавить окно..." в различных ситуациях ошибки. Согласно основному комментарию для ViewRootImpl, это "Вершина иерархии представления, реализующая необходимый протокол между View и WindowManager. Это по большей части внутренняя деталь реализации WindowManagerGlobal".
WindowManagerGlobal отслеживает несколько окон через три массива. Насколько я могу судить, ViewRootImpl фактически является новым окном, которым управляет WindowManagerGlobal.
Исходя из вышеизложенного, кажется, что вызов addView фактически создает новое окно (хотя оно по-разному называется представлением и окном), но для доступа к нему не предоставляется связанный класс Window, поэтому разработчик не может получить ручку к этому.
Мои вопросы:
- Существуют ли способы получить дескриптор экземпляра Window, кроме двух методов getWindow, упомянутых выше?
- Действительно ли addView создает окно и, если да, есть ли способ получить ручку к нему?
- Является ли что-либо еще выше неверным и, если да, то в каком отношении?
Спасибо! Барри