我有一个必须动态加载类的android应用程序,一个未定义数量的实现接口的jar类。
实际上,我查看一个目录并列出该目录中的所有 jar 文件我打开 jar 文件的清单并找到关联的类并列出它们。之后,我实例化了一个 dexClassLoader 来加载所有 jar 文件并查找我在清单中找到的类是否实现了我的接口。像这样,我可以拥有所有实现我的接口的类,而无需一开始就知道它们
要恢复,我有一个实现我的接口的类 jar 列表,但我的 android 应用程序和我都不知道该列表。每次我启动我的应用程序时,jar 类的列表都会改变。
但是当我尝试创建 DexClassLoader 时它失败了。我总是有一个空指针
DexClassLoader classLoader = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),dexOutputDir.getAbsolutePath(), null, ClassLoader.getSystemClassLoader());
为了进行测试,我使用了模拟器。我已经用我的 DDMS 将 jar 文件复制到目录 /data/data/com.example.Myappli/JarFilesDirectory/*.jar
请注意,我的 jar 文件包含 dex 文件
我读了很多关于这个的东西。一些权限问题我已经尝试了所有方法但没有找到解决方案
有人能帮助我吗 !!!
这里是 jar 文件清单的内容
清单版本:1.0
模块类:com.example.asktester.AskPeripheral
这是我的代码:
公共类模块加载器{
private static List<URL> urls = new ArrayList<URL>();
private static List<String> getModuleClasses(String folder)
{
List<String> classes = new ArrayList<String>();
//we are listing the jar files
File[] files = new File(folder).listFiles(new ModuleFilter());
for(File f : files)
{
JarFile jarFile = null;
try
{
//we open the jar file
jarFile = new JarFile(f);
//we recover the manifest
Manifest manifest = jarFile.getManifest();
//we recover the class
String moduleClassName = manifest.getMainAttributes().getValue("Module-Class");
classes.add(moduleClassName);
urls.add(f.toURI().toURL());
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if(jarFile != null)
{
try
{
jarFile.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
return classes;
}
private static class ModuleFilter implements FileFilter {
@Override
public boolean accept(File file) {
return file.isFile() && file.getName().toLowerCase().endsWith(".jar");
}
}
private static ClassLoader classLoader;
public static List<IPeripheral> loadModules(String folder, Context CurrentContext) throws IOException, ClassNotFoundException
{
List<IPeripheral> modules = new ArrayList<IPeripheral>();
List<String> classes = getModuleClasses(folder);
final File dexInternalStoragePath = new File(CurrentContext.getDir("dex", Context.MODE_PRIVATE),"ask.dex");
File dexOutputDir = CurrentContext.getDir("dex", Context.MODE_PRIVATE);
final File dexClasses = new File(CurrentContext.getDir("dex", Context.MODE_PRIVATE),"ASK.jar");
DexFile dexFile = DexFile.loadDex(dexClasses.getAbsolutePath(), dexOutputDir.getAbsolutePath(), 0);
DexClassLoader classLoader = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),dexOutputDir.getAbsolutePath(), null, ClassLoader.getSystemClassLoader());
//Class<?> myClass = classLoader.loadClass("com.example.asktester.AskPeripheral");
if(IPeripheral.class.isAssignableFrom(myClass )){
Class<IPeripheral> castedClass = (Class<IPeripheral>)myClass ;
IPeripheral module = castedClass.newInstance();
modules.add(module);
}
}
catch (ClassNotFoundException e1)
{
e1.printStackTrace();
}
catch (InstantiationException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
}
return modules;
}