我正在尝试列出Android设备上显示的所有UI元素。我是通过在adb shell中运行“dumpsys window windows | grep”Window#“来实现的。这给了我一个从窗口n到0的窗口列表。
我想知道输出顺序是如何确定的。窗口n在顶部,窗口0在堆栈底部吗?此外,这些字段是什么意思?例如,第一行如下所示
Window #64 Window{793212d u0 NavigationBar}:
值793212d和u0表示什么?
答案 0 :(得分:1)
关于输出顺序:
关于字段:
793212d
是通过System#identityHashCode获得的窗口的(唯一)ID。
u0
引用窗口所属的 user ID。用户ID与Unix UID不同,它是一个更高级的概念。 Android将多个Unix UID分组为一个用户ID,即前100.000个Unix UID属于用户ID 0,依此类推(reference)。为了确定窗口的用户ID,Android会查找窗口的Unix UID(每个应用程序都有自己的Unix UID),然后将Unix UID映射到用户ID。
NavigationBar
是窗口的标题。
技术细节:调用dumpsys window windows
时,这将在WindowManagerService
(link)处触发转储请求。此类具有类型mRoot
的成员RootWindowContainer
,转储请求将被转发到该成员link。相关代码为:
forAllWindows((w) -> {
if (windows == null || windows.contains(w)) {
pw.println(" Window #" + index[0] + " " + w + ":");
w.dump(pw, " ", dumpAll || windows != null);
index[0] = index[0] + 1;
}
}, true /* traverseTopToBottom */);
w
的类型为WindowState
,它将覆盖toString
,以获取您在String
输出中看到的dumpsys
表示形式(link )。相关代码为:
mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
+ " u" + UserHandle.getUserId(mOwnerUid)
+ " " + mLastTitle + (mAnimatingExit ? " EXITING}" : "}");
RootWindowContainer#forAllWindows
方法遍历mChildren
列表,该列表被指定为z顺序(link,link):
// List of children for this window container. List is in z-order as the children appear on
// screen with the top-most window container at the tail of the list.
protected final WindowList<E> mChildren = new WindowList<E>();
boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
if (traverseTopToBottom) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
if (mChildren.get(i).forAllWindows(callback, traverseTopToBottom)) {
return true;
}
}
...