Tengo una aplicación de Android que tiene que cargar dinámicamente de clase, un número indefinido de una clase jar que implementó una interfaz.¿Cómo puedo cargar un archivo jar de forma dinámica en una aplicación de Android (4.0.3)
De hecho, miro un directorio y una lista de todos los archivos jar que están en este directorio Abra el manifiesto del archivo jar y encuentre la clase asociada y enumérelas. Y después, instalé un dexClassLoader para cargar todos los archivos jar y para encontrar si las clases que he encontrado en el manisfest implementan mi interfaz. Así puedo tener toda la clase que implementó mi interfaz sin conocerlos al principio
Para reanudar, tengo una lista de clase jar que implementa mi interfaz pero la lista es desconocida por mi aplicación android y por mí. La lista de la clase jar puede cambiar cada vez que lance mi aplicación.
Pero cuando intenté crear el DexClassLoader falló. Siempre tengo un puntero nulo
DexClassLoader classLoader = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),dexOutputDir.getAbsolutePath(), null, ClassLoader.getSystemClassLoader());
Para hacer mi prueba utilicé el emulador. He copiado con mis DDMS los archivos jar en el directorio /data/data/com.example.Myappli/JarFilesDirectory/*.jar
en cuenta que el contenido de mi archivo JAR del archivo Dex
He leído un montón de todo esto Algunos problemas de permisos He intentado todo, pero no he encontrado la solución
¿Alguien me puede ayudar por favor?
aquí el contenido de un manifiesto de un archivo jar
Manifiesto-Version: 1.0
Módulo Clase: com.example.asktester.AskPeripheral
Aquí mi código:
clase pública ModuleLoader {
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;
}