Java 在Android中使用DexClassLoader将multple.APK文件作为插件加载
我正在用Android(5.0+)开发一个框架/应用程序,它需要能够在无需用户交互的情况下无声地安装额外的“插件”/“应用程序” 我开始研究DALVIK/ART DexClassLoader来实现这个功能。起初,它似乎工作得很好,我设法加载了第一个plugin.apk(我在Android studio中使用普通的gradle构建),它解析了plugin类,然后我将其制作为一个实例。然而,当代码到达第二个插件时,它无法加载插件类。我认为这与类加载器有关。我得到异常ClassNotFoundException。有人熟悉这个问题吗Java 在Android中使用DexClassLoader将multple.APK文件作为插件加载,java,android,plugins,dex,dexclassloader,Java,Android,Plugins,Dex,Dexclassloader,我正在用Android(5.0+)开发一个框架/应用程序,它需要能够在无需用户交互的情况下无声地安装额外的“插件”/“应用程序” 我开始研究DALVIK/ART DexClassLoader来实现这个功能。起初,它似乎工作得很好,我设法加载了第一个plugin.apk(我在Android studio中使用普通的gradle构建),它解析了plugin类,然后我将其制作为一个实例。然而,当代码到达第二个插件时,它无法加载插件类。我认为这与类加载器有关。我得到异常ClassNotFoundExce
private static Object ParseZipFile(Context context, File file) {
String path = file.getParentFile().getAbsolutePath() + "/" + getFilenameWithoutExtension(file) +"Install";
unzipPlugin(file, path); // /Download/Framework/plugins/someplugin.zip -> /Download/Framework/plugins/someplugin
String configPath = path+"/plugin.config";
String className = getClassNameFromConfig(configPath);
if (className == null) {
System.out.println("No plugin.config found in .zip");
return null;
}
File apkPath = new File(path);
File [] files = apkPath.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".apk");
}
});
for(File apkFile: files) {
File dexOutputDir = context.getDir("dex", Context.MODE_PRIVATE);
DexClassLoader dexClassLoader = new DexClassLoader(apkFile.getAbsolutePath(), dexOutputDir.getAbsolutePath(), null, context.getClassLoader());
try {
return GetPluginClass(dexClassLoader, className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
return null;
}
private static Object GetPluginClass(DexClassLoader classloader, String className) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
Log.v("loadDexClasses", "Searching for class : " + className);
Class<?> classToLoad = classloader.loadClass(className);
Object plugin = classToLoad.newInstance();
return plugin;
}
private静态对象ParseZipFile(上下文,文件){
字符串路径=file.getParentFile().getAbsolutePath()+“/”+getFilenameWithoutExtension(文件)+“安装”;
解压lugin(文件,路径);///Download/Framework/plugins/someplugin.zip->/Download/Framework/plugins/someplugin
字符串configPath=path+“/plugin.config”;
字符串className=getClassNameFromConfig(configPath);
if(className==null){
System.out.println(“在.zip中找不到plugin.config”);
返回null;
}
文件apkPath=新文件(路径);
File[]files=apkPath.listFiles(新文件名过滤器(){
@凌驾
公共布尔接受(文件目录,字符串名称){
返回名称.endsWith(“.apk”);
}
});
对于(文件apkFile:files){
文件dexOutputDir=context.getDir(“dex”,context.MODE\u PRIVATE);
DexClassLoader DexClassLoader=新的DexClassLoader(apkFile.getAbsolutePath(),dexOutputDir.getAbsolutePath(),null,context.getClassLoader());
试一试{
返回GetPluginClass(dexClassLoader,className);
}catch(classnotfounde异常){
e、 printStackTrace();
}捕获(非法访问例外e){
e、 printStackTrace();
}捕获(无此字段例外){
e、 printStackTrace();
}捕获(实例化异常e){
e、 printStackTrace();
}
}
返回null;
}
私有静态对象GetPluginClass(DexClassLoader classloader,String className)抛出ClassNotFoundException、NoSuchFieldException、IllegaAccessException、InstanceionException{
Log.v(“loadDexClasses”,“搜索类:“+className”);
Class classToLoad=classloader.loadClass(类名);
Object plugin=classToLoad.newInstance();
返回插件;
}
Context是运行插件管理代码的Android服务的上下文
这是堆栈跟踪
02-04 10:12:21.118 8304-8304/se.company.framework W/System.err: java.lang.ClassNotFoundException: Didn't find class "se.company.isa.IsaPlugin" on path: DexPathList[[zip file "/storage/emulated/0/Download/Framework/plugins/isaInstall/isa.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]
02-04 10:12:21.118 8304-8304/se.company.framework W/System.err: at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at se.company.pluginlib.PluginManager.GetPluginClass(PluginManager.java:204)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at se.company.pluginlib.PluginManager.ParseZipFile(PluginManager.java:151)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at se.company.pluginlib.PluginManager.loadDexClasses(PluginManager.java:122)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at fi.iki.elonen.SimpleWebServer.initPlugin(SimpleWebServer.java:125)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at fi.iki.elonen.SimpleWebServer.<init>(SimpleWebServer.java:111)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at se.company.framework.HttpdService.onStartCommand(HttpdService.java:33)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3010)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at android.app.ActivityThread.-wrap17(ActivityThread.java)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1442)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at android.os.Looper.loop(Looper.java:148)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5417)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at java.lang.reflect.Method.invoke(Native Method)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err: Suppressed: java.lang.ClassNotFoundException: Didn't find class "se.company.isa.IsaPlugin" on path: DexPathList[[zip file "/data/app/se.company.framework-1/base.apk"],nativeLibraryDirectories=[/data/app/se.company.framework-1/lib/arm64, /vendor/lib64, /system/lib64]]
02-04 10:12:21.120 8304-8304/se.company.framework W/System.err: at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
02-04 10:12:21.120 8304-8304/se.company.framework W/System.err: at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
02-04 10:12:21.120 8304-8304/se.company.framework W/System.err: at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
02-04 10:12:21.120 8304-8304/se.company.framework W/System.err: ... 16 more
02-04 10:12:21.120 8304-8304/se.company.framework W/System.err: Suppressed: java.lang.ClassNotFoundException: se.company.isa.IsaPlugin
02-04 10:12:21.120 8304-8304/se.company.framework W/System.err: at java.lang.Class.classForName(Native Method)
02-04 10:12:21.120 8304-8304/se.company.framework W/System.err: at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
02-04 10:12:21.120 8304-8304/se.company.framework W/System.err: at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
02-04 10:12:21.120 8304-8304/se.company.framework W/System.err: at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
02-04 10:12:21.120 8304-8304/se.company.framework W/System.err: ... 17 more
02-04 10:12:21.120 8304-8304/se.company.framework W/System.err: Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
02-04 10:12:21.118 8304-8304/se.company.framework W/System.err:java.lang.ClassNotFoundException:在路径:DexPathList[[zip文件”//storage/simulated/0/Download/framework/plugins/isaall/isa.apk”],nativeLibraryDirectories=[/vendor/lib64,/System/lib64]上未找到类
02-04 10:12:21.118 8304-8304/se.company.framework W/System.err:at-dalvik.System.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:位于se.company.pluginlib.PluginManager.GetPluginClass(PluginManager.java:204)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:at se.company.pluginlib.PluginManager.ParseZipFile(PluginManager.java:151)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:at se.company.pluginlib.PluginManager.loadDexClasses(PluginManager.java:122)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:at fi.iki.elonen.SimpleWebServer.initPlugin(SimpleWebServer.java:125)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:at fi.iki.elonen.SimpleWebServer.(SimpleWebServer.java:111)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:at se.company.framework.HttpdService.onStartCommand(HttpdService.java:33)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:at-android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3010)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:at-android.app.ActivityThread.-wrap17(ActivityThread.java)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:at-android.app.ActivityThread$H.handleMessage(ActivityThread.java:1442)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:at-android.os.Handler.dispatchMessage(Handler.java:102)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:at-android.os.Looper.loop(Looper.java:148)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:at-android.app.ActivityThread.main(ActivityThread.java:5417)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:at java.lang.reflect.Method.invoke(本机方法)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
02-04 10:12:21.119 8304-8304/se.company.framework W/System.err:抑制:java.lang.ClassNotFoundException:在路径:DexPathList[[zip文件”//data/app/se.company.framework-1/base.apk][/data/app/se.company.framework-1/lib/arm64、/vendor/lib64、/System/lib64]上未找到类“se.company.isa.isplugin”
02-04 10:12:21.120 8304-8304/se.company.framework W/System.err:at-dalvik.System.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
02-04 10:12:21.120 8304-8304/se.company.framework W/System.err:at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
02-