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");
Другие вопросы по тегам