Хотя вопрос старый, я отвечу, потому что я изо всех сил пытался найти четкий ответ на тот же вопрос для себя. Во-первых, я хотел бы подчеркнуть, что ясным требованием в вашем вопросе является загрузка класса из .apk, который еще не установлен на устройстве. Следовательно, вызов менеджера пакетов с помощью getPackageManager () и предоставление ему пути к пакету явно приведут к исключению NameNotFoundException, поскольку .apk , в котором есть пакет, не установлен на устройстве.
Таким образом, способ загрузки классов из файла .apk , который не установлен на устройстве (т. Е. У вас есть только файл .apk, хранящийся в каталоге на SDCARD), заключается в использовании DexClassLoader следующим образом:
1- Убедитесь, что у вас есть файл .apk в каталоге на вашей SDCARD. У меня есть Offloadme.apk в папке Download на моей SDCARD.
2- Добавьте разрешение на чтение в AndroidManifest.xml , чтобы приложение могло читать из манифеста.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
3- Используйте следующие определения, чтобы определить путь к .apk, имя класса внутри apk и имя метода в этом классе, которое вы хотите вызвать:
final String apkFile =Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download/Offloadme.apk";
String className = "com.khaledalanezi.offloadme.SimpleCalculator";
String methodToInvoke = "add";
4- Используйте DexClassLoader , чтобы загрузить .apk и вызвать метод add в классе SimpleCalculator , используя отражение следующим образом:
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();
}
Обратите внимание, что в моем простом примере я добавил два числа, используя метод add , доступный в классе SimpleCalculator , загруженном из файла Offloadme.apk , хранящегося в моя SDCARD и я смогли напечатать правильный ответ 11.