我正在尝试列出 Android 设备上显示的所有 UI 元素。我通过在 adb shell 中运行“dumpsys window windows | grep “Window #”来完成此操作。这会为我提供从窗口 n 到 0 的窗口列表。
我想知道输出顺序是如何确定的。窗口 n 位于堆栈顶部,窗口 0 位于堆栈底部吗?另外,字段是什么意思?例如第一行如下所示
Window #64 Window{793212d u0 NavigationBar}:
值 793212d 和 u0 表示什么?
最佳答案
关于输出顺序:
- 窗口按 z 顺序从上到下遍历,因此最上面的窗口首先出现。
关于字段:
793212d
是窗口的(唯一)ID,通过 System#identityHashCode 获取.u0
指的是窗口所属的用户 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 ) 处的转储请求。此类有一个 RootWindowContainer
类型的成员 mRoot
,转储请求将转发到该成员 ( 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
以获取您在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;
}
}
...
关于android - dumpsys 窗口 windows 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44256755/