You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android不使用已废弃DexFile获取指定包下所有类的实现方案

Android平台无需DexFile获取指定包名下类列表的实现方案

实现思路:通过反射获取BaseDexClassLoader内部的dexElements列表,遍历每个dex文件的类条目,过滤出目标包名下的类即可,全程不依赖已废弃的android.util.DexFile类。

fun getClasses(context: Context, targetPackage: String): List<Class<*>> {
    val classList = mutableListOf<Class<*>>()
    val classLoader = context.classLoader as? BaseDexClassLoader ?: return emptyList()

    // 反射获取pathList字段
    val pathListField = BaseDexClassLoader::class.java.getDeclaredField("pathList")
    pathListField.isAccessible = true
    val pathList = pathListField.get(classLoader)

    // 获取dexElements数组
    val dexElementsField = pathList.javaClass.getDeclaredField("dexElements")
    dexElementsField.isAccessible = true
    val dexElements = dexElementsField.get(pathList) as? Array<*> ?: return emptyList()

    for (element in dexElements) {
        // 获取当前element对应的dex文件
        val dexFileField = element.javaClass.getDeclaredField("dexFile")
        dexFileField.isAccessible = true
        val dexFile = dexFileField.get(element) as? dalvik.system.DexFile ?: continue

        // 遍历dex内的所有类名
        val entries = dexFile.entries()
        while (entries.hasMoreElements()) {
            val className = entries.nextElement()
            if (className.startsWith(targetPackage)) {
                try {
                    // 不需要排除内部类可删除以下判断
                    if (!className.contains("$")) {
                        val clazz = classLoader.loadClass(className)
                        classList.add(clazz)
                    }
                } catch (e: ClassNotFoundException) {
                    continue
                } catch (e: NoClassDefFoundError) {
                    continue
                }
            }
        }
    }
    return classList
}

注意事项

  • 代码中用到的dalvik.system.DexFile是系统内部类,不属于已废弃的公共API,目前全版本Android系统均可正常使用
  • 开启混淆时需要将目标包名下的类加入混淆白名单,否则类名被混淆后无法通过包名前缀匹配
  • 上述反射调用用到的内部字段均属于Android系统允许访问的灰/白名单,Android 9及以上版本无需额外配置反射豁免
  • 遍历dex文件耗时较高,不要在主线程调用该方法,建议放到子线程异步执行

内容的提问来源于stack exchange,提问作者jos76

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 07:36:03