2015-12-11 6 views
20

Ho un progetto e ha 2 sapori dei prodotti con i propri indici:Come risolvere l'errore di compilazione per l'aroma del prodotto, quando non si trova una fonte/risorsa referenziata ma non necessaria?

build.gradle:

android { 
    ... 
    productFlavors { 
      free { 
       applicationId "com.sample.free" 
       buildConfigField "boolean", "free", "true" 
      } 
      paid { 
       applicationId "com.sample" 
       buildConfigField "boolean", "free", "false" 
      } 
    } 
} 

e ho una classe (come PaidOperationClass) che viene utilizzato solo a paid sapore. Quindi, ho messo quella classe sotto la directory src/paid/java. E ho un'altra classe (come CommonClass) che viene utilizzata da entrambi i sapori. Così ho messo che sotto src/main/java directory:

src/main/ --> has CommonClass 
src/free/ 
src/paid/ --> has PaidOperationClass 

In CommonClass Ho un metodo come ad esempio:

if(!BuildConfig.FREE) { 
    PaidOperationClass.doSomeStuff(); 
} 

Così il PaidOperationClass viene fatto riferimento (ha un import) ma mai usata da accumulo libero.

Se si crea l'applicazione per il sapore paid, tutto funziona perfettamente. Ma se provo a crearlo per l'aroma free, fallisce perché la classe di riferimento ma non necessaria non viene trovata. Come si risolve questo senza la replica del codice (classe/metodo) (come mettere un manichino PaidOperationClass con il sapore free)? Ci sono delle opzioni di gradle che ignorano questo tipo di errori di compilazione durante la costruzione?

Modifica: Ho bisogno di una soluzione gradle che non necessiti di replica del codice. Forse uno script personalizzato basato su annotazioni, che rimuove il codice non necessario per i sapori del prodotto in fase di compilazione.

+3

No, devi aggiustarlo nel tuo codice. –

+0

@MimmoGrottoli si ma ci deve essere un modo semplice con gradle. – Devrim

+0

No, non c'è. Gradle è il sistema di generazione, non il codice dell'app. –

risposta

1

La soluzione più semplice potrebbe essere quella di creare una classe: IPaidOperations che si trova nella directory/src/main implementata da PaidOperationClass. Quindi usa l'interfaccia nella CommonClass.

+0

Penso che sia come creare una classe fittizia per altri gusti. Sto cercando una soluzione gradle che non avrà bisogno di replicare classi o risorse non necessarie. – Devrim

2

Non è possibile farlo, perché la dichiarazione di importazione si trova all'interno dello CommonClass e non è in grado di risolvere PaidOperationClass nel gusto gratuito.

Un modo per raggiungerlo è:

creare una classe vuota nel sapore libera:

public class PaidOperationClass{ 

    public static void doSomeStuff(){ 
     //do nothing..  
    } 
} 
1

Si fa riferimento il pacchetto paid dal pacchetto free se il vostro uso:

if(!BuildConfig.FREE) { 
    PaidOperationClass.doSomeStuff(); 
} 

Quindi suggerisco una delle due opzioni:

1.
Quindi, se si dispone di un pezzo di codice che non viene mai utilizzato, perché lo mantieni lì? Rimuoverlo e sostituirlo con:

if(!BuildConfig.FREE) { 
    // Do something within the imported packages. 
} 

In caso contrario, è necessario importare il pacchetto paid.

2.
o di avere due versioni del pacchetto free

free_paid e free_no_paid e rimuovere il riferimento al paid nel free_no_paid e utilizzare questo quando si compila senza paid e utilizzare il pacchetto free_paid quando si compila con paid.

+0

Il tuo primo suggerimento è irrilevante perché uso i sapori del prodotto gradle e ho diverse versioni di build che invocano diversi pezzi di codice (classi/metodi). Secondo uno significa una replica che è la stessa che attualmente faccio. Ho bisogno di una soluzione gradle che non necessiti di una replica. Forse uno script basato su annotazioni, che rimuove i codici non necessari per i gusti del prodotto in fase di compilazione. – Devrim

1

Un'altra soluzione è quella di creare due CommonClass es - sia in free e paid set sorgente (ma non in main) contenenti codice specifico di particolare sapore. Ad esempio: src/free/java/.../CommonClass.java:

doSomeStuff() { 
    doSomeFreeStuff();  
} 

src/paid/java/.../CommonClass.java:

doSomeStuff() { 
    doSomePaidStuff();  
} 

In tal caso il codice si trova in main set sorgente può riferire CommonClass#doSomeStuff() non importa quale sapore è costruito. Verrà compilato solo uno CommonClass per l'aroma particolare. In altre parole, invece di usare ifs manualmente, si consente a gradle di scegliere la classe appropriata da compilare.

È anche possibile estrarre codice molto comune (che non dipende da elementi specifici di free o paid) da CommonClass a classe astratta ie. BaseCommonClass inserito in main set di origine e lasciare estendere lo CommonClass.