Ho un'applicazione Android che deve caricare dinamicamente una classe, un numero indefinito di una classe jar che ha implementato un'interfaccia.Come posso caricare dinamicamente un file jar in un'applicazione Android (4.0.3)
Infatti, guardo una directory ed elenco tutti i file jar che si trovano in questa directory apro il manifest del file jar e trovo la classe associata e li elenco. E dopo, ho istanziato un dexClassLoader per caricare tutti i file jar e per scoprire se le classi che ho trovato nel manisfest implementano la mia interfaccia. Come questo posso avere tutta la classe che ha implementato la mia interfaccia senza conoscerli all'inizio
Per riprendere, ho una lista di jar di classe che implementano la mia interfaccia ma l'elenco è sconosciuto dalla mia applicazione Android e da me. L'elenco delle classi jar può essere modificato ogni volta che lancio la mia applicazione.
Ma quando ho provato a creare il DexClassLoader è fallito. Ho sempre un puntatore nullo
DexClassLoader classLoader = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),dexOutputDir.getAbsolutePath(), null, ClassLoader.getSystemClassLoader());
Per eseguire il test ho utilizzato l'emulatore. Ho copiato con i miei DDMS i file jar nella directory /data/data/com.example.Myappli/JarFilesDirectory/*.jar
noto che il mio contenuto del file jar il file di dex
Ho letto un sacco di cose su questo. Alcuni problemi di permessi Ho provato ogni cosa ma non ho trovato la soluzione
Qualcuno può aiutarmi per favore !!!
qui il contenuto di un manifesto di un file jar
Manifest-Version: 1.0
Module-Classe: com.example.asktester.AskPeripheral
Ecco il mio codice:
public class 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;
}