2010-05-25 19 views
17

Uderzyłem trochę ściany. Każda pomoc będzie doceniona. Mam aplikację, której chcę użyć DexClassLoader do załadowania innego pliku APK.Android - użycie DexClassLoader do załadowania pliku APK

Oto mój kod:

DexClassLoader dLoader = new DexClassLoader("/sdcard/download/test.apk","/sdcard/download",null,ClassLoader.getSystemClassLoader().getParent()); 
Class calledClass = dLoader.loadClass("com.test.classname"); 
Intent it=new Intent(this, calledClass); 
it.setClassName("com.test", "com.test.classname"); 
startActivity(it); 

Teraz już zainstalowany test.apk więc kiedy wpadłem powyższy kod to działało dobrze i uruchomiła aplikację. Jednak chcę być w stanie uruchomić to bez test.apk jest już zainstalowane (jak to byłoby pokonać cały punkt aplikacji). Więc odinstalowałem go i kiedy prowadził moją aplikację ponownie otrzymuję ten błąd:

android.content.ActivityNotFoundException: Unable to find explicit 
activity class {com.test/com.test.classname}; have you declared this 
activity in your AndroidManifest.xml. 

więc jestem trochę zakłopotany tutaj. Ta aktywność jest zadeklarowana w Manifeście pakietu APK, który próbuję uruchomić. Nie mogę tego zgłosić w moich aplikacjach. Manifest. Jakieś pomysły?

Dzięki Craig

Odpowiedz

-5

Nie można tego zrobić. Nawet jeśli masz dostęp do klas z zewnętrznego pliku, Android nadal ich nie zna. Nie uruchamiasz bezpośrednio działań, ale żądasz, aby Android je uruchomił, więc muszą zostać zarejestrowane/zainstalowane w systemie.

10

Spróbuj użyć Android PathClassLoader:

String packagePath = "com.mypackage"; 
    String classPath = "com.mypackage.ExternalClass"; 

    String apkName = null; 
    try { 
     apkName = getPackageManager().getApplicationInfo(packagePath,0).sourceDir; 
    } catch (PackageManager.NameNotFoundException e) { 
     // catch this 
    } 

    // add path to apk that contains classes you wish to load 
    String extraApkPath = apkName + ":/path/to/extraLib.apk" 

    PathClassLoader pathClassLoader = new dalvik.system.PathClassLoader(
      apkName, 
      ClassLoader.getSystemClassLoader()); 

    try { 
     Class<?> handler = Class.forName(classPath, true, pathClassLoader); 
    } catch (ClassNotFoundException e) { 
     // catch this 
    } 
7

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.

Powiązane problemy