学员投稿:wms优化改进dumpsys层级结构树显示具体层级数字

背景:

针对wms课程中经常讲解的窗口层级结构树部分,有学员反应有的看不出窗口具体位于0-36层的具体哪一层的问题。

在这里插入图片描述
比如想看Leaf:3:12中的下面Shell窗口的层级是啥,这个同学就不太好理解了,到底是位于第3层还是第12层呢?

在这里插入图片描述其实这个问题层级位于哪里,宏观上理解也容易,大家可以如下方式理解:
因为这里的Leaf:3:12本身属于一个范围节点,而且本身这个节点下面就一个子节点,也就是说3-12层都是最后都是只装了一个窗口,没有再细分其他层级窗口节点,所以你可以认为这个3-12是一个整体上的一层既可以。无论ShellDropTarget窗口位于3-12哪一层都不会运行这个窗口的显示顺序。
总结就是把3-12层看成一个整体层级一个大层既可以,反正3-12只有一个ShellDropTarget窗口,无论他是在3层,5层,12层都是不会影响他的在系统整体显示z轴顺序。

但是有学员提出,我就想要知道这个窗口具体的是位于哪一层,可否有办法呢?
在这里插入图片描述

这个问题我们的优秀学员“汽车人”在vip群就有进行详细回答,“汽车人”兄弟也算大家的师兄,给大家也分享过很多干货哈,最后感谢“汽车人”兄弟干货投稿,给大家分享了一个dumpsys 层级结构树的改进方案,带上window的具体0-36层级数字。

优秀学员汽车人投稿:

dumpsys activity containers命令查看层级结构时,发现有些WindowToken我们不知道它具体在0-36的哪一层,比如ShellDropTarget所属的windowToken,我们只知道它在3:12层这个区间,不知道具体哪一层。
在这里插入图片描述
在学习层级结构树时,我们知道windowToken其实是在WindowManagerPolicy的getWindowLayerFromTypeLw()方法中去看对应的层级,这里的关键就是知道type这个属性。
在这里插入图片描述
这个type其实是WindowToken的windowType属性,在WindowToken构造时被赋值,对应应用端添加窗口时传递的参数,比如:

mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;`

如果想要dumpsys activity containers命令也能查看到windowToken的具体层级很简单。

void dumpActivityContainersLocked(PrintWriter pw) {
        pw.println("ACTIVITY MANAGER CONTAINERS (dumpsys activity containers)");
        mRootWindowContainer.dumpChildrenNames(pw, "");
        pw.println(" ");
    }

顺着这个命令找对应代码,很快找到对每个层级信息的打印是在这个方法里:

 public void dumpChildrenNames(PrintWriter pw, String prefix, boolean isLastChild) {
        //省略
        pw.print(prefix + (isLastChild ? "└─ " : "├─ "));
        pw.println(getName()//这里会调用toString()
                + " type=" + actType
                + " mode=" + winMode
                + " override-mode=" + overrideWinMode
                + " requested-bounds=" + getRequestedOverrideBounds().toShortString()
                + " bounds=" + getBounds().toShortString());

        String childPrefix = prefix + (isLastChild ? "   " : "│  ");
        for (int i = getChildCount() - 1; i >= 0; --i) {
            final E cc = getChildAt(i);
            cc.dumpChildrenNames(pw, childPrefix, i == 0 /* isLastChild */);
        }
    }

注意此处的getName()其实是调用toString()方法,而WindowToken的toString()如下:
在这里插入图片描述
其实是打印了windowType的,而WindowToken本身就有方法获取对应层级:

 int getWindowLayerFromType() {
        return mWmService.mPolicy.getWindowLayerFromTypeLw(windowType, mOwnerCanManageAppTokens,
                mRoundedCornerOverlay);
    }

所以,只需要对toString()方法改成如下即可:

 @Override
    public String toString() {
        if (stringName == null) {
            stringName = "WindowToken{" + Integer.toHexString(System.identityHashCode(this))
                    + " type=" + windowType + " " + token + ",layer:"+getWindowLayerFromType()+"}";
        }
        return stringName;
    }

最终dumpsys activity containers命令效果:
在这里插入图片描述可以看到,WindowToken都能显示具体层级了,壁纸的专用WallpaperWindowToken我没修改,所以它没显示,不过也不需要。

再次感谢“汽车人”兄弟投稿,大家记得积极转发点赞哈。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值