java - Android:加载界面时DexClassLoader类加载失败

标签 java android classloader dalvik dexclassloader

简介:我试图在运行时从 classes.jar 中的 classes.dex 加载代码。我做了很多研究并在这上面花了很多时间,所以我真的需要帮助。

问题: 当我的 jar 包含一个简单的类时,它被成功加载。然而,在完全相同的情况下,当我的 jar 包含相同的类时,只是现在该类实现了一个接口(interface),加载此类失败并出现错误:

"Didn't find class "com.x.y.z.w.Patch" on path: DexPathList[[zip file "/data/user/0/x.y.z/app_dex/classes_dexed.jar"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]"

我还得到:

I/dalvikvm: Failed resolving Lcom/x/y/TestClassImpl; interface 4 'Lcom/x/y/TestClassInterface;'

环境: - 用于尝试加载类的函数:

(DexClassLoader 实例).loadClass & (DexFile 实例).loadClass.

具体来说:

方法一:

DexFile dx = DexFile.loadDex(jarInternalPath, File.createTempFile("opt", "dex", 
    context.getCacheDir()).getPath(), 0);
Class<?> targetClass = dx.loadClass(className, 
    ClassLoader.getSystemClassLoader()); // Error

方法二:

DexClassLoader dexClassLoader = new DexClassLoader(jarInternalPath,
    dexOutPath.getAbsolutePath(), null, ClassLoader.getSystemClassLoader());
Class<?> targetClass = dexClassLoader.loadClass(className); // Error
  • 集成环境:Android Studio 2.1.2
  • 测试设备:模拟器 Nexus 4(使用 API 16、19 和 23),以及搭载 Android 6.0.1 的物理 Nexus 5 设备
  • 最令人惊讶的事情:当我打印 dex 文件的类时,我看到了正确的类路径。我使用 DexFile 加载 dex 内容并打印其类路径。 此方法可识别正确的内容!这让我觉得这与 Android 权限或 Linux 权限有关。我不知道..

这是我的打印方法:

try {
    DexFile dx = DexFile.loadDex(jarInternalPath, File.createTempFile("opt", "dex",
        context.getCacheDir()).getPath(), 0);

    // Print all classes in the DexFile
    for (Enumeration<String> classNames = dx.entries(); classNames.hasMoreElements();) {
        String className = classNames.nextElement();
        Log.d(TAG, "Analyzing dex content, fonud class: " + className);
    }
} catch (IOException e) {
    Log.d(TAG, "Error opening " + jarInternalPath, e);
}
  • 附言似乎无关紧要,但也许并非如此: 我的主机应用程序、通用界面和新内容的实现都位于同一项目的 3 个不同模块中。应用的包名称为 x.y.z,接口(interface)的 pkgName 为 x.y.z.interface,实现的 pkgName 为 x.y.z.impl。

第二个项目我尝试了所有 3 个模块,1 个模块无法以同样的方式工作。

请帮忙!

最佳答案

这不足以加载您的类(class)。您必须更改系统类加载器,以便以动态和编程方式从 dex 中使用您自己的类。如果不是,你不能使用你的接口(interface)或类或其他什么。

如果你想动态加载类,首先从 dexfile 或 dexclassloader 加载类,然后使用它。

例子,

Class<?> myOwnClass = MyDexClassLoader.loadClass("com.example.my");

关于java - Android:加载界面时DexClassLoader类加载失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38101183/

相关文章:

java - Java 中的继承,表面类型与实际类型

java - TimerTask 和广播接收器 onReceive

android - 删除谷歌日历中的单次事件

java - 从 sbt 程序集运行 uber jar 会导致错误 : Could not find or load main class

java.net.ConnectException : after adding weblogic-application. xml

java - 使用抽象类向接口(interface)添加方法

java - 如何滚动到 RecyclerView 的底部?滚动到位置不起作用

Java <-> Python : share objects

android - 无法打开 HAXM 设备 : ERROR_FILE_NOT_FOUND

android - 搜索未知 Activity (java.lang.ClassNotFoundException)