Cargar el archivo DEX dinámicamente en Android 5.0

Antes de Android 5.0 podía cargar archivos de DEX dinámicamente usando DexClassLoader y llamando el método de loadClass() pero con la última versión de Androide obtengo un ClassNotFoundException .

Esto es lo que estoy haciendo:

  1. Generar archivo DEX.

     ../android-sdk/android-sdk-linux_86/build-tools/21.1.1/dx --dex --output=bin/output.dex bin/output.jar 
  2. Cree un DexClassLoader.

     DexClassLoader cl = new DexClassLoader( dexFile.getAbsolutePath(), odexFile.getAbsolutePath(), null, mContext.getClassLoader()); 
  3. Llame a cl.loadClass("myMethod");

Soy consciente de que ART utiliza dex2oat para generar un archivo ELF que es el cargado por ART pero en el paso 2 estoy generando un archivo ODEX así que no soy lo que hay que hacer en ART para cargar un archivo DEX en tiempo de ejecución, yo ?

    One Solution collect form web for “Cargar el archivo DEX dinámicamente en Android 5.0”

    Actualizar

    Esto funciona tanto en Dalvik como en ART: new DexClassLoader(jarredDex.getAbsolutePath(), context.getDir("outdex", Context.MODE_PRIVATE).getAbsolutePath(), null, context.getClassLoader()); Donde jarredDex es un archivo jar con classes.dex . Jar se puede obtener ejecutando dx --dex --output=filename.jar your/classes/dir .


    Respuesta original

    He tomado un ejemplo de código de este artículo . Pero ART utiliza PathClassLoader lugar de PathClassLoader de Dalvik. Este código se prueba en el emulador con Android 6 y en Xiaomi con Android 5.1 y funciona bien:

     // Before the secondary dex file can be processed by the DexClassLoader, // it has to be first copied from asset resource to a storage location. File dexInternalStoragePath = new File(getDir("dex", Context.MODE_PRIVATE), SECONDARY_DEX_NAME); try (BufferedInputStream bis = new BufferedInputStream(getAssets().open(SECONDARY_DEX_NAME)); OutputStream dexWriter = new BufferedOutputStream(new FileOutputStream(dexInternalStoragePath))) { byte[] buf = new byte[BUF_SIZE]; int len; while((len = bis.read(buf, 0, BUF_SIZE)) > 0) { dexWriter.write(buf, 0, len); } } catch (IOException e) { throw new RuntimeException(e); } try { PathClassLoader loader = new PathClassLoader(dexInternalStoragePath.getAbsolutePath(), getClassLoader()); Class<?> toasterClass = loader.loadClass("my.package.ToasterImpl"); Toaster toaster = (Toaster) toasterClass.newInstance(); toaster.show(this, "Success!"); } catch (ReflectiveOperationException e) { throw new RuntimeException(e); } 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.