Mam aplikację na Androida, która musi ładować dynamicznie klasę, niezdefiniowaną liczbę klasy jar, która zaimplementowała interfejs.Jak mogę załadować plik jar dynamicznie w aplikacji na Androida (4.0.3)
W rzeczywistości patrzę na katalog i wyświetlam wszystkie pliki jar, które znajdują się w tym katalogu. Otwieram manifest pliku jar i znajduję skojarzoną klasę i wyświetlam je. Po dodaniu elementu dexClassLoader załadowałem wszystkie pliki jar i sprawdziłem, czy klasy, które znalazłem w interfejsie manisfest implementują mój interfejs. W ten sposób mogę mieć całą klasę, która zaimplementowała mój interfejs, nie znając ich na początku. Aby kontynuować, mam listę słoików klas, które implementują mój interfejs, ale lista jest nieznana przez moją aplikację Android i przeze mnie. Lista klasy słoików może być zmieniana za każdym razem, gdy uruchamiam moją aplikację.
Ale kiedy próbowałem utworzyć DexClassLoader, nie udało się. Zawsze mam wskaźnik zerowy
Do mojego testu użyłem emulatora. Mam skopiowane z moich DDMS pliki jar do katalogu /data/data/com.example.Myappli/JarFilesDirectory/*.jar
Zauważ, że moje zawartość pliku dek
pliku JAR dużo czytam o tym. Niektóre problemy z pozwoleniami Próbowałem wszystkich rzeczy, ale nie znalazłem rozwiązania
Czy ktoś może mi pomóc, proszę!
tu treść manifestu pliku jar
Manifest-Version: 1.0
Module-Klasa: com.example.asktester.AskPeripheral
Oto mój kod:
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;
}