2013-07-03 13 views
21

Sto tentando di configurare con Gradle un progetto che contiene alcune librerie esterne. Con Gradle I è possibile configurare diverse configurazioni ambientali (con una classe all'interno di un file di configurazione) per l'applicazione principale utilizzando le varianti di costruzione in modo da poter eseguire il codice in base a queste variabili.Crea varianti in Gradle per un progetto di libreria in Android

Il problema è che come posso fare lo stesso per un progetto di libreria? Ho creato questa libreria per questo progetto e vorrei impostare diverse varianti di compilazione per diversi scenari.

Come esempio: Nella Libreria, quando si esegue in modalità di debug, quindi stampare tutti i registri in modo che possa vederli durante lo sviluppo. In modalità di rilascio no.

struttura dei file:

src ----- > debug -> java -> config -> PlayerEnvConfig 
      main -> com.mypackagename -> etc... 
      release -> java -> config -> PlayerEnvConfig 

Codice in debug: pacchetto di configurazione;

/** 
* Environment configuration for Release 
*/ 
public final class PlayerEnvConfig { 
    public static final boolean USE_REPORTING = true; 
    public static final boolean USE_ANALYTICS = true; 
    public static final boolean USE_LOGGING = false; 
    public static final boolean USE_DEBUG_LOGGING = false; 
    public static final boolean USE_DEBUGING = false; 
} 

Codice in release:

package config; 

/** 
* Environment configuration for Release 
*/ 
public final class PlayerEnvConfig { 
    public static final boolean USE_REPORTING = true; 
    public static final boolean USE_ANALYTICS = true; 
    public static final boolean USE_LOGGING = false; 
    public static final boolean USE_DEBUG_LOGGING = false; 
    public static final boolean USE_DEBUGING = false; 
} 

Il problema è che per il progetto principale che posso usare questa build tipi di configurare diversamente la domanda di diversi scenari, ma come posso fare lo stesso per la Progetto di biblioteca?

Perché al momento da quello che ho letto in http://tools.android.com/tech-docs/new-build-system/user-guide la libreria utilizzerà solo la modalità di debug durante il test.

Qualche idea?

Grazie!

risposta

12

Non sono sicuro di cosa non funzioni con la configurazione ma della necessità, lo farei in modo diverso.

Nel file gradle build è possibile utilizzare la parola chiave buildConfig per aggiungere una riga specifica alla classe generata BuildConfig.java.

Così si potrebbe aggiungere fare qualcosa di simile nella vostra build.gradle:

release { 
     buildConfig "public static final String USE_REPORTING = true;" 
    } 
    debug { 

     buildConfig "public static final String USE_REPORTING = false;" 
    } 

E così avere un solo PlayerEnvConfig con

public static final boolean USE_REPORTING = BuildConfig.USE_REPORTING; 

O anche più PlayerEnvConfig e utilizzare direttamente la classe BuildConfig.


EDIT Dal momento che un aggiornamento, la sintassi è cambiato:

buildConfigField "<type>", "<name>", "<value>" 
+7

Grazie tbruyelle L'ho provato (mu ch più intelligente in questo modo btw) ma il problema rimane ancora. Il problema si verifica nel fatto che quando si costruisce per eseguire l'applicazione le librerie sono sempre costruite in modalità di rilascio (anche se ho selezionato la modalità di debug in Android Studio). Nel link che ho postato prima lo spiega. Ma esiste qualche soluzione? "Il tipo di debug viene utilizzato dall'applicazione di test. Il tipo di versione viene utilizzato dai progetti che utilizzano la libreria." –

0

Questo non è possibile con progetti di libreria come lei stesso ha ricordato.

Si potrebbe semplicemente modificare il progetto di libreria in un progetto di applicazione. Sembra funzionare bene (almeno in teoria, non l'ho mai provato).

L'altro modo sarebbe quello di sovrascrivere quella classe nel progetto dell'applicazione. La classe del progetto dell'applicazione verrà scelta al momento della fusione e i valori saranno disponibili.

+0

Per quanto ne so, i moduli applicativi non possono avere dipendenze da altri moduli applicativi.Aveva anche un riferimento per questo, proprio non riesco a trovarlo più –

+0

Sì. L'ho scoperto anch'io. Era possibile con gli anziani sistema di costruzione credo non sia stato propagato al gradle –

3

AGGIORNAMENTO: dal momento della pubblicazione di questo articolo, sono stati compiuti molti progressi nel processo di sviluppo del gradle, pertanto questa risposta potrebbe non essere la procedura consigliata e le nuove modifiche potrebbero addirittura frenarlo. Usa la tua discrezione.

Credo che ci sia un po 'di confusione sull'intera struttura e configurazione del progetto. Diciamo che si ha la seguente configurazione build.gradle

sourceSets { 

    main { 
     manifest.srcFile 'src/main/AndroidManifest.xml' 
     java.srcDirs = ['src/main/java'] 
     //resources.srcDirs = ['src/main'] 
     //aidl.srcDirs = ['src/main'] 
     //renderscript.srcDirs = ['src/main'] 
     res.srcDirs = ['src/main/res'] 
     assets.srcDirs = ['src/main/assets'] 
    } 

    debug.setRoot('build-types/debug') 
    release.setRoot('build-types/release') 
} 

la struttura delle cartelle di progetto deve essere il più seguire

project_root 
    -src 
     -main 
     -java 
      -com 
       -example 
    -build-types 
     -debug 
     -java 
      -com 
       -example 
        -FooBar.java 
     -release 
     -java 
      -com 
       -example 
        -FooBar.java 

FooBar.java non deve essere in prooject_root/src/main/java/com/example. Deve essere nella cartella debug e release che deve risiedere all'esterno della cartella src ma all'interno della cartella build-types. Questo è configurato dal metodo setRoot('build-types/*****'). Un sacco di persone vengono confuse dal vedere "debug/java" e "main/java", dove il successivo viene fatto riferimento in modo 'src/main/java' dalla presentazione e finisce per mettere 'debug/java' in src, il cartella sbagliata. Spero che questo aiuto.

Per ulteriori ambiente complesso che coinvolge altre librerie, è possibile controllare la mia risposta qui https://stackoverflow.com/a/19918834/319058

4

Questo è documentato in https://code.google.com/p/android/issues/detail?id=52962. Come hai scoperto, il tipo di build non viene propagato ai progetti di libreria e non c'è una buona soluzione. Se si ha il controllo sul codice del progetto della libreria, è possibile rendere lo stato di debug una variabile globale mutabile e impostarlo dall'applicazione principale all'avvio. È un po 'un hack, e ha lo svantaggio che il compilatore non può ottimizzare i percorsi di codice inutilizzati lontano dalle build di rilascio, ma a meno che qualcosa di insolito stia succedendo dovrebbe funzionare.

0

As Scott indica che si tratta di un problema noto di Gradle. Come soluzione alternativa, è possibile utilizzare questo metodo, che utilizza la riflessione per ottenere il valore del campo dal app (non la libreria):

/** 
* Gets a field from the project's BuildConfig. This is useful when, for example, flavors 
* are used at the project level to set custom fields. 
* @param context  Used to find the correct file 
* @param fieldName  The name of the field-to-access 
* @return    The value of the field, or {@code null} if the field is not found. 
*/ 
public static Object getBuildConfigValue(Context context, String fieldName) { 
    try { 
     Class<?> clazz = Class.forName(context.getPackageName() + ".BuildConfig"); 
     Field field = clazz.getField(fieldName); 
     return field.get(null); 
    } catch (ClassNotFoundException e) { 
     e.printStackTrace(); 
    } catch (NoSuchFieldException e) { 
     e.printStackTrace(); 
    } catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

Per ottenere il campo DEBUG, per esempio, basta chiamare questo dal tuo Activity:

boolean debug = (Boolean) getBuildConfigValue(this, "DEBUG"); 

ho anche condiviso questa soluzione sul AOSP Issue Tracker.

14

E 'una risposta @bifmadei da google code issue e aiuta per me:

provare ad impostare questo nel progetto di dipendenza

android { 
    publishNonDefault true 
    ... 
} 

e questo nel progetto che lo utilizza

dependencies { 
    releaseCompile project(path: ':theotherproject', configuration: 'release') 
    debugCompile project(path: ':theotherproject', configuration: 'debug') 
} 

Presa da qui: https://code.google.com/p/android/issues/detail?id=66805

+0

Questo ha funzionato molto bene per me.Nota che puoi usare anche customTipi di build.Ho un buildType per simulatore quindi aggiungo simulatorCompile al mio file gradle.Se hai configurato correttamente, quando si cambia Build Variant tramite AndroidStudio 1.2.2, la Variant Build corretta scorrerà tra i moduli dipendenti: – biddster

+0

Sfortunatamente 'releaseCompile' non funziona in gradle-experimental. –

Problemi correlati