Android: загрузка класса DexClassLoader не выполняется при загрузке интерфейса
Введение: я пытаюсь загрузить код во время выполнения с classes.dex
это внутри classes.jar. Я провел много исследований и потратил много времени на это, поэтому мне действительно нужна помощь.
Проблема: когда мой jar содержит простой класс, он успешно загружен. Однако в точно такой же ситуации, когда мой jar содержит тот же класс, только теперь, когда этот класс реализует интерфейс, загрузка этого класса завершается с ошибкой:
"Не найден класс"com.xyzwPatch"по пути: DexPathList[[zip-файл"/data/user/0/xyz/app_dex/classes_dexed.jar"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]"
Я также получаю:
I / dalvikvm: Не удалось разрешить Lcom/x/y/TestClassImpl; интерфейс 4 'Lcom/x/y/TestClassInterface;'
Окружение: - Функции, используемые для загрузки класса:
(Экземпляр DexClassLoader).loadClass & (Экземпляр DexFile).loadClass.
В частности:
Способ 1:
DexFile dx = DexFile.loadDex(jarInternalPath, File.createTempFile("opt", "dex",
context.getCacheDir()).getPath(), 0);
Class<?> targetClass = dx.loadClass(className,
ClassLoader.getSystemClassLoader()); // Error
Способ 2:
DexClassLoader dexClassLoader = new DexClassLoader(jarInternalPath,
dexOutPath.getAbsolutePath(), null, ClassLoader.getSystemClassLoader());
Class<?> targetClass = dexClassLoader.loadClass(className); // Error
- IDE: Android Studio 2.1.2
- Тестовые устройства: эмулятор Nexus 4 (с API 16, 19 и 23), а также Physical Nexus 5 Device с Android 6.0.1
- Самое удивительное: когда я печатаю классы файла dex, я вижу правильный путь к классу. Я использую DexFile, чтобы загрузить содержимое dex и распечатать пути к его классам. Этот метод распознает правильное содержание! Это заставляет меня думать, что что-то связано с разрешениями Android или Linux. Я не знаю..
Это мой метод печати:
try {
DexFile dx = DexFile.loadDex(jarInternalPath, File.createTempFile("opt", "dex",
context.getCacheDir()).getPath(), 0);
// Print all classes in the DexFile
for (Enumeration<String> classNames = dx.entries(); classNames.hasMoreElements();) {
String className = classNames.nextElement();
Log.d(TAG, "Analyzing dex content, fonud class: " + className);
}
} catch (IOException e) {
Log.d(TAG, "Error opening " + jarInternalPath, e);
}
- PS Кажется неуместным, но, возможно, это не так: приложение My Host, общий интерфейс и реализация нового контента - все они находятся в 3 разных модулях одного проекта. Приложение имеет имя пакета xyz, интерфейс имеет pkgName xyzinterface, а реализация имеет pkgName xyzimpl.
Второй проект, который я пробовал со всеми тремя модулями в одном, один модуль не работал одинаково.
Пожалуйста помоги!
1 ответ
Этого недостаточно для загрузки вашего класса. Вы должны изменить системный загрузчик классов, чтобы использовать свой собственный класс из dex динамически и программно. если нет, вы не можете использовать свой интерфейс или класс или что-то еще.
если вы хотите загружать класс динамически, сначала загрузите класс из dexfile или dexclassloader и используйте его.
пример,
Class<?> myOwnClass = MyDexClassLoader.loadClass("com.example.my");