Aunque la pregunta es viejo, voy a responder porque me ha costado un poco para encontrar una respuesta clara para su misma pregunta para mí. En primer lugar, me gustaría resaltar que un requisito claro en su pregunta es cargar una clase desde una .apk que no esté ya instalada en el dispositivo. Por lo tanto, llamar al gestor de paquetes utilizando getPackageManager() y proporcionarle la ruta del paquete conducirá claramente a NameNotFoundException porque el .apk que tiene el paquete no está instalado en el dispositivo.
Por lo tanto, el camino a seguir acerca de las clases de carga desde un archivo .apk que no está instalado en el dispositivo (es decir, es suficiente con el apk almacenada en un directorio en su sdcard) es mediante el uso DexClassLoader de la siguiente manera:
1- Asegúrese de tener el archivo .apk en un directorio en su SDCARD. Tengo el mío Offloadme.apk en la carpeta de descarga en mi SDCARD.
2- Agregue permiso de lectura en su AndroidManifest.xml para permitir que su aplicación lea del manifiesto.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
3- utilizar las siguientes definiciones para definir la ruta de la apk, el nombre de clase dentro de la apk, y el nombre del método en el que la clase que desea invocar:
final String apkFile =Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download/Offloadme.apk";
String className = "com.khaledalanezi.offloadme.SimpleCalculator";
String methodToInvoke = "add";
4 - Use DexClassLoader para cargar el archivo.apk y llamar a la añadir método en el SimpleCalculator clase mediante la reflexión de la siguiente manera:
final File optimizedDexOutputPath = getDir("outdex", 0);
DexClassLoader dLoader = new DexClassLoader(apkFile,optimizedDexOutputPath.getAbsolutePath(),
null,ClassLoader.getSystemClassLoader().getParent());
try {
Class<?> loadedClass = dLoader.loadClass(className);
Object obj = (Object)loadedClass.newInstance();
int x =5;
int y=6;
Method m = loadedClass.getMethod(methodToInvoke, int.class, int.class);
int z = (Integer) m.invoke(obj, y, x);
System.out.println("The sum of "+x+" and "+"y="+z);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Tenga en cuenta que en mi ejemplo sencillo, añadí dos números usando el añadir método disponible en el clase SimpleCalculator cargado desde el Offloadme.apk archivo almacenado en mi SDCARD y pude imprimir la respuesta correcta que es 11.