android-fragments 如何使用“adb shell dumpsys activity”获取碎片的全名

mgdq6dx1  于 2022-11-14  发布在  Android
关注(0)|答案(1)|浏览(137)

出于测试的目的,我使用adb shell dumpsys activity <activity_name>转储前台Activity中的片段信息。
问题是转储的片段名称只包含类名而不包含其全名(全名是指包名+类名)。例如,如果片段的全名为aaa.bbb.ccc.MyFragment,则转储的片段名称将为MyFragment
如果应用未进行模糊处理,这不是一个严重的问题。但是,当应用进行模糊处理时,转储的片段名称将大多类似于单个字符(例如,abc,...)。因此,很难仅通过转储的名称来区分两个不同的片段。
为什么Android操作系统选择只转储类名?转储全名有什么困难?adb用户是否有其他选项可以在运行时获取片段的全名?

kr98yfug

kr98yfug1#

根据Android源代码,该片段的toString()使用DebugUtils.buildShortClassTag()打印类名。
Fragment.java

@Override
    public String toString() {
        StringBuilder sb = new StringBuilder(128);
        DebugUtils.buildShortClassTag(this, sb);
        if (mIndex >= 0) {
            sb.append(" #");
            sb.append(mIndex);
        }
        if (mFragmentId != 0) {
            sb.append(" id=0x");
            sb.append(Integer.toHexString(mFragmentId));
        }
        if (mTag != null) {
            sb.append(" ");
            sb.append(mTag);
        }
        sb.append('}');
        return sb.toString();
    }

DebugUtils.java

public static void buildShortClassTag(Object cls, StringBuilder out) {
        if (cls == null) {
            out.append("null");
        } else {
            String simpleName = cls.getClass().getSimpleName();
            if (simpleName == null || simpleName.isEmpty()) {
                simpleName = cls.getClass().getName();
                int end = simpleName.lastIndexOf('.');
                if (end > 0) {
                    simpleName = simpleName.substring(end+1);
                }
            }
            out.append(simpleName);
            out.append('{');
            out.append(Integer.toHexString(System.identityHashCode(cls)));
        }
    }

我们可以看到buildShortClassTag()使用cls.getClass().getSimpleName()来打印类名。
综上所述,我们无法获得片段的全名,除非我们改变Android框架的源代码并构建一个自定义的操作系统。但这种解决方案并不完美,因为AndroidX中的片段有自己的逻辑来打印片段信息。AndroidX库被打包在一个apk中,它们也被混淆。

相关问题