Загрузка удаленных кодов Android
Я разрабатываю библиотеку для Android, которая требует частых обновлений с центрального сервера. Я думал, насколько это было бы хорошо, если бы моя библиотека могла обновить себя, или если бы я мог просто освободить библиотеку начальной загрузки, которая загружает целевую библиотеку, когда приложение будет установлено.
Я вижу этот класс в 1.5, называемом "DexClassLoader", но, похоже, в Интернете, как и в документах API, кажется мало ценного. Кто-нибудь использовал это для сценария, который я описал?
Кроме того, разрешают ли условия Android Market такие вещи?
Ответы
Ответ 1
Я успешно использовал DexClassLoader. Важно предоставить dexOutputDir
, который на самом деле можно записать в ваше приложение, поэтому не /data/dalvik-cache
. В противном случае журнал покажет одну или две строки о невозможности записи там, а затем ClassNotFoundException
.
cl = new DexClassLoader("/full/path/com.example.apk",
getFilesDir().getAbsolutePath(),// /data/data/foo/files
null, // native lib path, I haven't used this
MyClass.class.getClassLoader());
// This doesn't make Class.forName() work, instead I do this:
Class<?> foo = cl.loadClass("com.example.foo");
Чтобы сделать работу Class.forName()
, вы можете попробовать Thread.setContextClassLoader() (у меня ее нет).
Ответ 2
Действительно, то, что вы хотите, поддерживается и работает. DexClassLoader работает не так, как ожидалось для меня, но следующий код работает нормально.
DexFile df = new DexFile(new File("/data/app/my_downloaded_lib.apk"));
ClassLoader cl = getClassLoader();
Class clazz = df.loadClass("com/my/lib/MyClass", cl);
О рыночном вопросе, я не вижу никаких проблем с этим, но вы должны обязательно прочитать EULA.
Ответ 3
DexClassLoader
- правильный ответ. Приложения никогда не должны использовать DexFile
напрямую (это предназначено для использования загрузчиками классов).
Вы можете использовать внешнее хранилище (/sdcard
) или область личных данных приложения для параметра dexOutputDir
. Внешнее хранилище обычно больше, но если карта выбрасывается, ваше приложение будет убито, а из-за отсутствия прав на использование файлов для третьей стороны будет проще заменить ваш код. Это может привести к тому, что вредоносные приложения заставят ваше приложение выполнять произвольные действия. (Если вы хотите сделать это в любом случае, получите путь через Environment.getExternalStorageDirectory()
; требуется разрешение WRITE_EXTERNAL_STORAGE
.)
Область частных приложений (получить путь от Context.getFilesDir()
) более безопасна, а также имеет преимущество в том, что она автоматически очищается, если приложение удалено. Это рекомендуемый подход.