2014-10-21 6 views
5

Ich brauche eine JAR-Datei in einem Haupt/Assets-Verzeichnis in einem Android-Projekt. Es ist wichtig, dass sich die JAR-Datei dort befindet.Wie behalte ich eine JAR-Datei extern, benutze aber trotzdem ihre Klassen in meinem Android-Projekt?

Mit meinem Android-Projekt gibt es eine Möglichkeit, diese Jar-Datei in meinem Code zu referenzieren und seine Klassen zu verwenden?

Um klar zu sein Ich möchte nicht das Glas zum Hauptprojekt einmal kompiliert hinzufügen.

BEARBEITEN: Ich habe versucht, den Link unten und es scheint, die Class-Datei, die ich angegeben habe, zu laden. Aber ich versuche, Konstruktorargumente für die dynamisch geladene Klasse zu definieren.

android-custom-class-loading-sample

EDIT2

es fast. Ich habe bestätigt, dass die Klasse aus meinem classes.jar geladen wurde. Ich stecke es jedoch fest.

In der Zeile licenseValidatorClazz.getConstructor erhalte ich den Fehler unten. Ich vermute, dass ich etwas aus meiner Interface-Datei vermisse?

java.lang.NoSuchMethodException: [interface com.google.android.vending.licensing.Policy, Schnittstelle com.google.android.vending.licensing.DeviceLimiter, Schnittstelle com.google.android.vending.licensing.LicenseCheckerCallback, int, Klasse java.lang.String, Klasse java.lang.String]

public Class licenseValidatorClazz = null; 
    public LicenseValidator validator; 

    ... 

    // Initialize the class loader with the secondary dex file. 
    DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(), 
    optimizedDexOutputPath.getAbsolutePath(), 
    null, 
    mContext.getClassLoader()); 

     try { 
      // Load the library class from the class loader. 
      licenseValidatorClazz = cl.loadClass("com.google.android.vending.licensing.LicenseValidator"); 

      validator = (LicenseValidator) licenseValidatorClazz.getConstructor(Policy.class,DeviceLimiter.class,LicenseCheckerCallback.class,int.class,String.class,String.class).newInstance(ddd, new NullDeviceLimiter(), 
        callback, generateNonce(), mPackageName, mVersionCode); 

     } catch (Exception exception) { 
      // Handle exception gracefully here. 
      exception.printStackTrace(); 
     } 

ich habe eine Schnittstelle, die die Funktionen enthält, die der geladenen Klasse zu übergeben.

public interface LicenseValidator 
{ 
    public LicenseCheckerCallback getCallback(); 
    public int getNonce(); 
    public String getPackageName(); 
    public void verify(PublicKey publicKey, int responseCode, String signedData, String signature); 
    public void handleResponse(int response, ResponseData rawData); 
    public void handleApplicationError(int code); 
    public void handleInvalidResponse(); 
} 
+0

welche Build-Tool verwenden Sie? – AesSedai101

+0

Ich benutze Android Studio. – zeroprobe

Antwort

4

ein externes Glas zu verwenden, mit Ihrer Anwendung verknüpft werden und es während der Laufzeit verwenden, muss es in Dalvik-Format sein, da normale Gläser nicht unter dalvikVM arbeiten können.

  1. Ihre Dateien konvertieren das dx-Tool
  2. mit aapt cmd, diesen classes.dex zu Ihrer JAR-Datei hinzufügen.
  3. Jetzt kann dieses Glas, das Dateien im Dalvik-Format enthält, in unser Projekt geladen werden.

Here ist ein Beitrag, der das Verfahren erläutert, um es zu erreichen.

+0

Verwaltet, um das DX-Tool zu verwenden. Ich denke, ich wäre in Ordnung mit einer einfachen Klasse. Aber ich versuche, einen Teil der Android-LVL-Bibliothek in ein Jar zu verschieben. Scheint ziemlich schwierig zu sein. – zeroprobe

0

Sie sollten die Services API ausprobieren - java.util.ServiceLoader

Sie eine Service-Schnittstelle und ihre Implementierungen in Ihrem Glas definieren.

Dann definieren Sie die Dienste in der JAR-Datei im Verzeichnis META-INF/services /. Zum Beispiel listen Sie in der Datei 'META-INF/services/com.my.project.MyService' die Providerklassen auf.

# Known MyService providers. 
com.my.project.MyServiceBarImpl # The original implementation for handling "bar"s. 
com.my.project.MyServiceFooImpl # A later implementation for "foo"s. 

Dann in Ihrer Haupt-Code-Basis, können Sie eine MyService Instanz mit den ServiceLoader instanziiert:

for (MyService service : ServiceLoader.load(MyService.class)) { 
    //Perform some test to determine which is the right MyServiceImpl 
    //and then do something with the MyService instance 
} 

Diese Beispielen mehr oder weniger direkt von der API genommen werden, obwohl ich mir verändert habe die Paketnamen, um sie etwas weniger störend zu lesen.

1

Es gibt Schritte, um dies zu erreichen.

  1. Sie müssen eine Kopie Ihrer JAR-Datei in den privaten internen Speicher Ihrer Anwendung kopieren.

    1. Mit dem dx Werkzeug innerhalb der Android-Ordner, müssen Sie mit der JAR-Datei zugeordnet ist, eine classes.dex Datei erzeugen. Das dx-Tool wird an der Stelle /android-sdks/build-tools/19.0.1 sein (diese Datei von der Dalvik VM benötigt wird, kann einfach jar nicht von der Dalvik VM gelesen werden))

    2. Mit den aapt Tool-Befehl, der auch an der gleichen Stelle ist, müssen Sie die Classes.dex der JAR-Datei hinzufügen.

This JAR-Datei geladen DexClassLoader dynamisch über werden könnte.

Wenn Sie ein JAR aus einer eigenen Bibliothek erstellen, müssen Sie diese Schritte (1-4) jedes Mal durchführen, wenn sich der Quellcode Ihrer Bibliothek ändert. Sie können diese Schritte also automatisieren, indem Sie ein Shell-Skript (in Mac/Linux/Ubuntu) oder Batch-Skripte (in Windows) erstellen. Sie können auf diesen Link verweisen, um zu verstehen, wie Sie Shell-Skripte schreiben.

Hinweis: Eine Situation für die Implementierung dieser Methode ist, wenn es unmöglich ist, die JAR-Dateien direkt zum Build-Pfad des Kernprojekts hinzuzufügen und zur Laufzeit dynamisch geladen werden müssen. In normalen Fällen könnten die JAR-Dateien zum Build-Pfad hinzugefügt werden.

Bitte überprüfen Sie diesen Link für den detaillierten Code und die Implementierung.

How to load a jar file at runtime

Android: How to dynamically load classes from a JAR fil e?

Hoffe das hilft !!