2014-10-21 10 views
5

Ho bisogno di avere un file jar situato in una directory principale/delle risorse all'interno di un progetto Android. È importante che il file jar si trovi lì.Come mantenere un file jar esterno, ma continui a utilizzare le sue classi nel mio progetto Android?

Con il mio principale progetto Android c'è un modo per fare riferimento a questo file jar nel mio codice e di utilizzare le sue classi?

Per essere chiari, non desidero aggiungere il jar al progetto principale una volta compilato.

EDIT: Ho provato il collegamento seguente e sembra che carichi il file di classe che ho indicato. Ma sto cercando di definire come definire gli argomenti del costruttore per la classe caricata dinamicamente.

android-custom-class-loading-sample

EDIT2

Ci siamo quasi. Ho confermato che la classe è stata caricata dal mio classes.jar. Sono bloccato a istanziare però.

Sulla linea licenseValidatorClazz.getConstructor ottengo l'errore sotto. Immagino che mi manchi qualcosa del mio file di interfaccia?

java.lang.NoSuchMethodException: [Interfaccia com.google.android.vending.licensing.Policy, interfaccia com.google.android.vending.licensing.DeviceLimiter, interfaccia com.google.android.vending.licensing.LicenseCheckerCallback, int, classe java.lang.String, java.lang.String classe]

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(); 
     } 

ho un'interfaccia che contiene le funzioni per passare alla classe caricata.

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

quale strumento di costruzione stai usando? – AesSedai101

+0

Sto utilizzando Android Studio. – zeroprobe

risposta

4

Per utilizzare un vaso esterna per essere associate con l'applicazione e utilizzarlo durante il funzionamento, deve essere in formato dalvik poiché vasi normali non possono lavorare sotto dalvikVM.

  1. Convertire i file utilizzando lo strumento dx
  2. utilizzando aapt cmd, aggiungere tali classes.dex al file jar.
  3. Ora questo jar che contiene i file in formato dalvik può essere caricato nel nostro progetto.

Here è un post che spiega la procedura per realizzarlo.

+0

Gestito per utilizzare lo strumento DX. Penso che sarei OK con una classe semplice. Ma sto provando a spostare parte della libreria LVL di Android in un barattolo. Sembra abbastanza difficile. – zeroprobe

0

Si dovrebbe provare le API di servizio - java.util.ServiceLoader

si definisce un'interfaccia di servizio e le sue implementazioni nel vostro vaso.

package com.my.project; 
public interface MyService { ... } 
public class MyServiceBarImpl implements MyService { ... } 
public class MyServiceFooImpl implements MyService { ... } 

Poi si definiscono i servizi contenuti all'interno del file jar nella/servizi/directory META-INF. Ad esempio, nel file "META-INF/services/com.my.project.MyService" vengono elencate le classi del provider.

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

Poi, nella vostra base di codice principale, è possibile creare un'istanza di un'istanza MyService con la ServiceLoader:

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 
} 

Questi esempi sono presi più o meno direttamente dal API, anche se ho cambiato i nomi dei pacchetti per renderli leggermente meno fastidiosi da leggere.

1

Ci sono passaggi per farlo.

  1. si deve fare una copia del file JAR nella memoria interna privata del vostro aplication.

    1. Utilizzando l' strumento dx all'interno della cartella di Android, è necessario generare un file classes.dex associato al file JAR. Lo strumento dx sarà al /android-sdks/build-tools/19.0.1 posizione (questo file è necessario per il Dalvik VM, semplicemente vaso non può essere letto dal Dalvik VM))

    2. Utilizzando la aapt comando dello strumento che si trova anche nella stessa posizione, è necessario aggiungere il classes.dex al file JAR.

This file JAR potrebbe essere caricato utilizzando dinamicamente DexClassLoader.

Se si sta creando un JAR da una libreria qualsiasi, è necessario eseguire questa procedura (1-4) ogni volta che si verifica una modifica del codice sorgente della libreria. Quindi puoi automatizzare questa procedura creando uno script di shell (in Mac/Linux/Ubuntu) o script batch (in Windows). Puoi refere questo link per capire come scrivere script di shell.

Nota: Una situazione per l'attuazione di questo metodo è che, quando non è possibile aggiungere i file JAR direttamente al percorso di generazione del progetto di base e devono essere caricati in modo dinamico in fase di esecuzione. In casi normali i file JAR potrebbero essere aggiunti al percorso di generazione.

Si prega di controllare questo link per il codice dettagliato e l'implementazione.

How to load a jar file at runtime

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

Spero che questo aiuti !!

Problemi correlati