references - multidex install android
Android, cómo usar DexClassLoader para reemplazar dinámicamente una actividad o servicio (1)
Comenzar una actividad a través de DexClassLoader será muy difícil, ya que no instaló el APK, por lo que no hay nada para manejar su intención.
Debería tener la misma clase de actividad en su plataforma APK y declararla en AndroidManifest.xml. Luego, debe cambiar el ClassLoader actual a su DexClassLoader deseado. Como resultado, se iniciará su plugin APK. (Nota: "plataforma APK" se refiere a la aplicación que ya está instalada en el teléfono, mientras que "plugin APK" se refiere al archivo apk guardado en su tarjeta SD).
La aplicación de la plataforma debería ser algo como esto:
public static ClassLoader ORIGINAL_LOADER;
public static ClassLoader CUSTOM_LOADER = null;
@Override
public void onCreate() {
super.onCreate();
try {
Context mBase = new Smith<Context>(this, "mBase").get();
Object mPackageInfo = new Smith<Object>(mBase, "mPackageInfo")
.get();
//get Application classLoader
Smith<ClassLoader> sClassLoader = new Smith<ClassLoader>(
mPackageInfo, "mClassLoader");
ClassLoader mClassLoader = sClassLoader.get();
ORIGINAL_LOADER = mClassLoader;
MyClassLoader cl = new MyClassLoader(mClassLoader);
//chage current classLoader to MyClassLoader
sClassLoader.set(cl);
} catch (Exception e) {
e.printStackTrace();
}
}
class MyClassLoader extends ClassLoader {
public MyClassLoader(ClassLoader parent) {
super(parent);
}
@Override
public Class<?> loadClass(String className)
throws ClassNotFoundException {
if (CUSTOM_LOADER != null) {
try {
Class<?> c = CUSTOM_LOADER.loadClass(className);
if (c != null)
return c;
} catch (ClassNotFoundException e) {
}
}
return super.loadClass(className);
}
}
Para obtener más código, puede visitar https://github.com/Rookery/AndroidDynamicLoader
Estoy leyendo el código fuente de Android para encontrar un método más elegante para implementar esta función. Si tienes alguna idea, no dudes en contactarme.
Estoy tratando de hacer algo similar a esta publicación de stackoverflow . Lo que quiero hacer es leer la definición de una actividad o servicio de la tarjeta SD. Para evitar problemas de permisos de manifiesto, creo una versión de shell de esta actividad en el .apk, pero trato de reemplazarla con una actividad del mismo nombre que reside en la tarjeta SD en el tiempo de ejecución. Desafortunadamente, puedo cargar la definición de la clase de actividad desde la tarjeta SD usando DexClassLoader, pero la definición de la clase original es la que se ejecuta. ¿Hay alguna forma de especificar que la nueva definición de clase reemplace a la anterior, o alguna sugerencia para evitar los problemas de permiso manifiesto sin proporcionar realmente la actividad necesaria en el paquete? El código de ejemplo:
ClassLoader cl = new DexClassLoader("/sdcard/mypath/My.apk",
getFilesDir().getAbsolutePath(),
null,
MainActivity.class.getClassLoader());
try {
Class<?> c = cl.loadClass("com.android.my.path.to.a.loaded.activity");
Intent i = new Intent(getBaseContext(), c);
startActivity(i);
}
catch (Exception e) {
En lugar de lanzar com.android.my.path.to.a.loaded.activity
especificado en /sdcard/mypath/My.apk
, se inicia la actividad cargada estáticamente en el proyecto.