DexClassLoader на Android Honeycomb
Я работаю над проектом, который пытается загрузить внешнюю библиотеку через
DexClassLoader. Это очень хорошо работало в версии 2.3:
public class FormularDisplayLoader {
public final static String PATH ="/data/data/at.mSystem.client/files/mSystem_Client_FormularLibrary.jar";
private DexClassLoader classLoader;
public FormularDisplayLoader(Context context){
this.context = context;
this.classLoader = new DexClassLoader("/data/data/at.mSystem.client/
files/mSystem_Client_FormularLibrary.jar",
context.getFilesDir().getAbsolutePath(),
null,
FormularDisplayLoader.class.getClassLoader());
}
public View getDisplay(String className) throws ErrorCodeException{
try {
Class c = classLoader.loadClass(className);
Method m = c.getMethod("getDisplay", Context.class);
View ret = (View) m.invoke(c.newInstance(), context);
return ret;
} catch (Exception e) {
e.printStackTrace();
throw new
ErrorCodeException(FormularErrorCode.NO_DISPLAY_AVAILABLE_FOR_FORMULAR);
}
}
}
К сожалению, при попытке перенести это приложение в Honeycomb (потому что
фактической целью для этого приложения являются планшеты), DexClassLoader выбрасывает
исключение:
02-23 09:30:58.221: ERROR/dalvikvm(8022): Can't open dex cache '/data/
dalvik-cache/
[email protected]@[email protected]@[email protected]':
No such file or directory
02-23 09:30:58.221: INFO/dalvikvm(8022): Unable to open or create
cache for /data/data/at.mSystem.client/files/
mSystem_Client_FormularLibrary.jar (/data/dalvik-cache/
[email protected]@[email protected]@[email protected])
02-23 09:30:58.231: WARN/System.err(8022):
java.lang.ClassNotFoundException:
at.mSystem.client.formular.contract.ContractListFormularDisplay in
loader [email protected]
02-23 09:30:58.241: WARN/System.err(8022): at
dalvik.system.DexClassLoader.findClass(DexClassLoader.java:240)
02-23 09:30:58.241: WARN/System.err(8022): at
java.lang.ClassLoader.loadClass(ClassLoader.java:548)
02-23 09:30:58.261: WARN/System.err(8022): at
java.lang.ClassLoader.loadClass(ClassLoader.java:508)
02-23 09:30:58.261: WARN/System.err(8022): at
at.mSystem.client.system.formularmodule.formular.FormularDisplayLoader.getDisplay(FormularDisplayLoader.java:
35)
Кажется, что DexClassLoader игнорирует 2-й параметр
(dexOutputDir), так как значение
context.getFilesDir(). getAbsolutePath() в моем примере - это "/data/data/
at.mSystem.client/файлы".
Есть ли у вас идеи, как это решить? Или это какая-то
сотовая ошибка?
Спасибо,
Роланд
Ответы
Ответ 1
Я знаю, что это старый пост, но мне недавно был нужен ответ на него без обновления до Android 3.1, поэтому я решил поделиться своим решением.
Я использовал класс "DexFile" вместо "DexClassLoader", так как он позволял мне передавать выходной файл, тем самым обойти проблему с игнорированием выходного каталога.
Здесь мой код:
final File dexClasses = new File("/sdcard/dexcontainer.zip");
DexFile dexFile = DexFile.loadDex(dexClasses.getAbsolutePath(), getFilesDir().getAbsolutePath() + "/outputdexcontainer.dex", 0);
Enumeration<String> classFileNames = dexFile.entries();
while (classFileNames.hasMoreElements())
{
String className = classFileNames.nextElement();
dexFile.loadClass(className, classLoader);
}
Надеюсь, это поможет кому-то.
Ответ 2
Глядя на историю изменений, это должно быть исправлено в Android 3.1.