我正在尝试列出 Android 设备上显示的所有 UI 元素。我通过在 adb shell 中运行“dumpsys window windows | grep “Window #”来做到这一点。这给了我一个从窗口 n 到 0 的窗口列表。
我想知道输出顺序是如何确定的。窗口 n 在栈顶,窗口 0 在栈底吗?另外,这些字段是什么意思?例如第一行显示如下
Window #64 Window{793212d u0 NavigationBar}:
值 793212d 和 u0 表示什么?
关于输出顺序:
关于字段:
793212d
是窗口的(唯一)ID,使用System #identityHashCode获得。
u0
指的是窗口所属的用户ID 。用户 id 与 Unix UID 不同,它是一个更高级的概念。Android 将多个 Unix UID 分组为属于一个用户 ID,即前 100.000 个 Unix UID 属于用户 ID 0,依此类推(参考)。为了确定窗口的用户 ID,Android 会查找窗口的 Unix UID(每个应用程序都有自己的 Unix UID),然后将 Unix UID 映射到用户 ID。
NavigationBar
是窗口的标题。
技术细节:调用时,会在(链接)dumpsys window windows
处触发转储请求。此类有一个type 的成员,转储请求将被转发到该成员(链接)。相关代码为:WindowManagerService
mRoot
RootWindowContainer
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
is 类型WindowState
,它覆盖toString
以获得您在输出(链接)String
中看到的表示。相关代码为:dumpsys
mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
+ " u" + UserHandle.getUserId(mOwnerUid)
+ " " + mLastTitle + (mAnimatingExit ? " EXITING}" : "}");
该RootWindowContainer#forAllWindows
方法遍历mChildren
列表,该列表指定为 z 顺序(链接、链接):
// 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;
}
}
...