Подтвердить что ты не робот

Возможно ли динамически загружать класс Activity из библиотеки jar на sdCard и фактически использовать его?

У меня есть файл .jar на sdCard (я использовал инструмент dx для компиляции обычного .jar для dex.. в противном случае андроид будет жаловаться во время выполнения)

Класс, который я хочу использовать, на самом деле представляет собой Activity и "use", я имею в виду Inflate!

A) Я заметил, что если я загружаю класс таким образом, загруженный класс будет иметь пакетный пакет пакета parrent-класса (тот, в котором я запускаю код: example: real-package of class в библиотеке jar: "com.something" и my-app-package: "com.wonderfull" → загруженный класс находится в "com.wonderfull.com.something":)) → проверено: он сохраняет оригинальный пакет, так же, как в библиотеке

B) В случае "наилучшего" сценария я получаю эту ошибку:

Невозможно создать экземпляр активности ComponentInfo {com.appno2/com.appno1.futureLib.LibActivity}: java.lang.ClassNotFoundException: com.appno1.futureLib.LibActivity в loader dalvik.system.PathClassLoader [/data/app/com.appno2-1.apk]

C) В манифесте я разместил Activity (тот, который будет загружен динамически) следующим образом:

активность   Android: name= "com.appno1.futureLib.LibActivity"   android: label = "@string/app_name" > /Деятельность >

Итак, я повторяю вопрос из заголовка: возможно ли динамически загружать класс Activity из библиотеки jar на sdCard и фактически использовать его?

В случае "Зачем вам это нужно?" - просто любопытные! + как концепция: возможность загрузить фактический код приложения (в форме банки чего-то) сразу после того, как пользователь ввел действительную лицензию

Обновление: - этот идеал работает с фрагментами (значит, класс, который должен быть импортирован, является фрагментом)

Текущее заключение: - возможно, существуют классы lame java или даже классы, связанные с интерфейсом Android в внешнем .jar(например, на SDCard или для загрузки из интернета и т.д.) и загружать их динамически при необходимости. О да: вы не можете работать так, как это делают:(.. возможно даже не службы..

Дополнительная информация # 1: Возможно ли динамически загружать библиотеку во время выполнения из приложения Android?

Дополнительная информация # 2: http://android-developers.blogspot.ro/2011/07/custom-class-loading-in-dalvik.html

Regardin URLClassLoader: это работает (без привлечения DalvikClassLoader - ClassNotFoundException & & obviosly: по-прежнему не может надуть активность, загруженную таким образом)

File file = new File("/sdcard/myLib.jar");
File tmpDir = getDir("dex", 0);
ClassLoader loader = new URLClassLoader(new URL[]{file.toURI().toURL()}, this.getClass().getClassLoader());
DexClassLoader classloader = new DexClassLoader(file.getAbsolutePath(), tmpDir.getAbsolutePath(), null, loader);
Class<Object> classref = (Class<Object>) classloader.loadClass("packageInLib.ClassName");
Object myInstance = classref.getConstructor().newInstance();

Or instead of "loadClass"
Class<?> classref = Class.forName("packageInLib.ClassName", true, dalvikClassLoader);
4b9b3361

Ответ 1

У меня были похожие сценарии.

Если u не помещается ниже кодов в AndroidManifest.xml

<activity android:name="com.appno1.futureLib.LibActivity" android:label="@string/app_name" > </activity>

U будет ниже ошибки.

10-21 17:04:25.860: E/AndroidRuntime(11050): Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class {... ...}; have you declared this activity in your AndroidManifest.xml?

Но если вы зарегистрируете активность в своем клиентском приложении, тогда будет получено java.lang.ClassNotFoundException.

Загрузитель попытался выполнить поиск com.appno1.futureLib.LibActivity в [/data/app/com.appno2-1.apk]. Очевидно, этого не ожидается. Я считал, что com.appno.futureLib.LibActivity находится в файле .jar.

Если есть способ позволить загрузчику искать LibActivity в файле .jar, проблема может быть решена.

Ответ 2

Вы можете сканировать файлы JAR для своего содержимого и загружать классы с помощью URLClassloader. Это стандартная Java (у меня есть реализация JavaSE, если вы хотите взглянуть), но она включена в Android API, поэтому я думаю, что она должна работать нормально.

URLClassloader на developer.android.com

В основном вы получаете ClassLoader (предупреждение о грязном коде!):

File file = new File("/sdcard/jars/myDynamicLib.jar");
ClassLoader loader = new URLClassLoader(new URL[]{file.toURI().toURL()}, this.getClass().getClassLoader());

вам нужны ваши метаданные XML или что-то другое, что нужно загрузить:

jar.getInputStream(jar.getEntry("myMetaData.xml"));

Вы загружаете информацию (способ ее анализа зависит от формата, который вы используете: вы можете уже загрузить его с вашим приложением) - теперь у вас есть имя класса.

И теперь вы просто пытаетесь загрузить:

Class<?> classref = Class.forName(className, true, loader);
instance = (MyType) classref.getConstructor().newInstance();

Опять же, хотя я не пробовал такие вещи на Droid, я думаю, что это должно работать нормально.

Вот и все. Вам нужен путь к файлу JAR и имя загружаемого класса. Класс загрузчик вытащит классы из JAR для вас.