我正在尝试学习在 Android 中动态加载类(.dex/.jar)。我从教程和 Stack Overflow 问题( tutorial、this和this )中收集了基本思想,但我未能实现动态加载类文件并不断给出ClassNotFound
异常的目的。
我的步骤简要:
按照文章中的说明创建了一个 Java 文件。
public class DynamicClass { public static void main(String[] args){ print(); } public static void print() { System.out.println("Hello Dynamic"); } }
将 java 源代码转换为 .class(结果 = DynamicClass.class)
javac DynamicClass.java
dx
使用Android SDK 中的工具创建 jar 文件。(结果 = 带有 classes.dex 的 dynamic.jar)dx --dex --output=dynamic.jar DynamicClass.class
获得 .jar 文件后,我将其推送到 /sdcard/ (在模拟器和设备上都进行了测试)
模拟器:Android 6.0 和设备:Android 11.0
加载类的简要代码:
try { String dexPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "dynamic.jar"; Log.d("DYNAMIC_TEST","dexPath: "+dexPath); final File tmpDir = getDir("dex", 0); // temporary file creation for .exists() check File dexFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "dynamic.jar"); if (dexFile.exists()){ // dexFile location is same as dexPath location Log.d("DYNAMIC_TEST", "File Found"); DexClassLoader dexClassLoader = new DexClassLoader(dexPath, tmpDir.getAbsolutePath(), null, this.getClass().getClassLoader()); Class dynamicClass = dexClassLoader.loadClass("DynamicClass"); Method printMethod = dynamicClass.getMethod("print"); printMethod.invoke(dynamicClass.newInstance()); Log.d("DYNAMIC_TEST","Success"); } else { Log.d("DYNAMIC_TEST", "File NOT Found"); } }catch (Exception e){ Log.d("DYNAMIC_TEST", "Exception: "+ e.toString()); }
我不断收到ClassNotFound
异常。
我错过了什么?为什么无法加载这个简单的类文件:(?
我的清单:
- 确保代码能够获取加载的文件 (<File>.exists())。代码能够获取文件。只是无法加载类。
- 确保dynamic.jar在其中包含一个classes.dex条目。(这是因为DexClassLoader想要一个.jar / .apk文件,其中包含classes.dex条目)
- 尝试在模拟器和设备上运行代码(两者都有不同的 Android 版本)。
异常说明:
异常:java.lang.ClassNotFoundException:在路径上找不到类“DynamicClass”:DexPathList[[zip file "/storage/emulated/0/dynamic.jar"],nativeLibraryDirectories=[/system/lib64, /vendor/lib64 ]]
包含包裹后的异常。
异常:java.lang.ClassNotFoundException:在路径上找不到类“mypack.DynamicClass”:DexPathList [[zip 文件“/storage/emulated/0/mypack.jar”],nativeLibraryDirectories=[/system/lib64,/vendor /lib64]]