Choć pytanie jest stary, odpowiem, bo zmagał się trochę znaleźć jasną odpowiedź dla samego pytania dla siebie. Po pierwsze, chciałbym podkreślić, że wyraźnym wymaganiem w pytaniu jest załadowanie klasy z pliku .apk, który nie jest jeszcze zainstalowany na urządzeniu. Dlatego wywołanie menedżera pakietów za pomocą metody getPackageManager() i podanie ścieżki pakietu wyraźnie doprowadzi do wywołania NameNotFoundException, ponieważ pakiet .apk nie jest zainstalowany na urządzeniu.
Więc droga o klasach załadowczych z apk pliku, który nie jest zainstalowany na urządzeniu (czyli masz tylko apk przechowywane w katalogu na sdcard) jest za pomocą DexClassLoader następująco:
1- Upewnij się, że plik .apk znajduje się w katalogu na Twojej karcie SD. Mam mój Offloadme.apk w folderze pobierania na mojej karcie SD.
2- Dodaj uprawnienia do odczytu w swoim AndroidManifest.xml, aby umożliwić aplikacji odczyt z manifestu.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
3- należy stosować następujące definicje zdefiniować ścieżkę apk, nazwę klasy wewnątrz apk i nazwę metody w tej klasie, które chcesz wywołać:
final String apkFile =Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download/Offloadme.apk";
String className = "com.khaledalanezi.offloadme.SimpleCalculator";
String methodToInvoke = "add";
4 - Użyj DexClassLoader, aby załadować.apk i nazywają dodać metodę w SimpleCalculator klasy przy użyciu odbicie w następujący sposób:
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();
}
pamiętać, że w moim prostym przykładzie, dodałem dwa numery uzywajac dodać metody dostępne w SimpleCalculator klasie załadowany z pliku Offloadme.apk przechowywanego na moim SDCARD i mogłem wydrukować poprawną odpowiedź, która jest 11.