Assigned
Status Update
Comments
py...@gmail.com <py...@gmail.com> #2
Also confirmed issue persists on 4.4.
su...@google.com <su...@google.com> #3
There are a lot of expensive accessories I've purchased or been gifted that quit workin with android 4.2. Android devs need to get on this. 3 broken versions and numerous minor updates and it hasn't even been triaged yet. Completely unprofessional.
ra...@google.com <ra...@google.com>
br...@gmail.com <br...@gmail.com> #4
We are loyal to Android as and they treat us like this.. I have a google device and yet it still is not fixed.
Description
Suggested changes
Note: these changes might seem view specific but they really apply to both the View framework and Compose on Android, since Compose still runs in an Android root view / window.
1. New
registerWindowViewAttachCallback
APIAdd a new
registerWindowViewAttachCallback
API or similar to eitherWindowInspector
(which already hasWindowInspector.getGlobalWindowViews()
) orApplication
(which hasregisterActivityLifecycleCallbacks()
), e.g. :The callback would be called synchronously on every call to
WindowManager.addView()
Alternatively, although maybe less generic and ideal, a
Application.registerDialogLifecycleCallback
API could help achieve similar goals (see below on "why").2. Ability to pull the Window from a root view
When a window is a PhoneWindow then its root view is a DecorView (private class) which holds on to the associated Window. There should be a way to pull the associated Window object (if the view is associated to a phone window object), in order to be able to leverage the Window APIs (most importantly being able to swap out the window callback).
Why
1. New
registerWindowViewAttachCallback
APIIn API 29 the Android Framework addedhttps://cs.android.com/android/_/android/platform/frameworks/base/+/1761cfac39d5ee17f2e4f8eef485c38a08624533 ) to help with Android Studio UI inspection and for the Espresso testing library to be able to traverse the view hierarchy for all attached windows at a given point in time.
WindowInspector.getGlobalWindowViews()
which provides a list of root views, one view per window attached in the current process. This was added (inHowever, today, there is still no public API for knowing when new window views are added.
This is critical for observability libraries: a root view provides access to the ViewTreeObserver and potentially the associated window, if any (if moving forward with suggested change 2).
Today, developers can already listen to new activity windows and the associated root views by registering a ActivityLifecycleCallbacks on the Application and pulling the window & root view in onCreate().
However, there's absolutely no support for any non activity window, such as Dialog based windows, or direct calls to
WindowManager.addView()
. Dialog based windows are critical for any sheet implementation, and generally large screens where it's more common to see layered UI with distinct windows.The recommended approach today would be to write additional code next to every Dialog.show() call or WindowManager.addView() call, which is not reasonable in large codebases where developers might import 3rd party libraries that they don't control that bring their own UI.
One note: for symmetry purposes it'd probably be nice to be told when root views are added AND when they're removed. However, the latter kinda already exists, since you can set an attach state change listener on the root view.
2. Ability to pull the Window from a root view
This one will probably be more controversial: Android offers a public Window class which IIRC is only used for windows created by dialogs and activities. The Window API is useful, especially the ability to set a Window callback (for instance to listen to all touch & key events). Unfortunately, you can only get the Window from a Dialog or Activity instance, and while there is
registerActivityLifecycleCallbacks()
, there is no dialog equivalent. So the proposal here is either to be able to pull the Window from a view hierarchy (if there's one), i.e. similar to ViewTreeObserver but optional (yeaaah maybe not ideal). Or provide some other way to get the window objects when there is such a window object.Seriously but why?!
All these asks might sound a little crazy. Here's the thing though, we absolutely need ways to know about new windows if we're to take observability seriously.
I already implemented these APIs using reflection (please don't yell) and they've been critical both for detecting root view leaks in LeakCanary, as well as reporting observability metrics in large codebases.
Here's how I do it today:
Now, all these crazy hacks allow me to build the nice APIs that we need, which are defined here:https://github.com/square/curtains
Let me show you some real usages that we can't do today using the public APIs:
JankStats.createAndTrack(window, jankFrameListener)
but without a way to get all windows this only captures a subset of the windows which jank can happen.