13

Ho uno script di build Gradle che utilizza un processore di annotazioni (annotazioni Android) per generare codice. L'edificio andava bene fino a quando ho aggiunto un nuovo aroma Pro. Posso creare l'aroma gratuito ma quando creo il sapore Pro il processore delle annotazioni non viene eseguito. Ciò causa codice mancante e la compilazione fallisce.Gradle + Annotations + Flavors = non eseguirà il processore delle annotazioni

Ecco il mio script:

buildscript { 
    repositories { 
     maven { url 'http://repo1.maven.org/maven2' } 
    } 
    dependencies { 
     classpath 'com.android.tools.build:gradle:0.5.+' 
    } 
} 
apply plugin: 'android' 

repositories { 
    mavenCentral() 
    maven { 
     url 'https://oss.sonatype.org/content/repositories/snapshots/' 
    } 
} 


ext.androidAnnotationsVersion = '3.0-SNAPSHOT'; 

configurations { 
    apt 
} 


dependencies { 
    compile files('libs/android-support-v13.jar') 
    compile fileTree(dir: 'libs', include: '*.jar') 
    apt "org.androidannotations:androidannotations:${androidAnnotationsVersion}" 
    compile "org.androidannotations:androidannotations-api:${androidAnnotationsVersion}" 
} 

android { 
    compileSdkVersion 17 
    buildToolsVersion "17.0.0" 


    defaultConfig { 
     minSdkVersion 7 
     targetSdkVersion 17 

     versionCode 29 
     versionName "2.0.3" 
     packageName "com.MyCompany.MyApp" 

    } 

    productFlavors { 
     free { 
      buildConfig "final public static boolean PRO_VERSION = false;" 
     } 
     pro { 
      packageName "com.MyCompany.MyApp.Pro" 
      versionName (versionName + ".Pro") 
      buildConfig "final public static boolean PRO_VERSION = true;" 
     } 
    } 

    buildTypes { 
     release { 
      buildConfig "final public static String BASE_URL = \"http://data.MyCompany.com/\";", \ 
         "final public static String APP_NAME = \"com.MyCompany.MyApp\";" 
     } 
     debug { 
      buildConfig "final public static String BASE_URL = \"http://192.168.1.15/GDM/\";", \ 
         "final public static String APP_NAME = \"com.MyCompany.MyApp\";" 
     } 
    } 

} 

def getSourceSetName(variant) { 
    return new File(variant.dirName).getName(); 
} 

android.applicationVariants.all { variant -> 
    def aptOutputDir = project.file("build/source/apt") 
    def aptOutput = new File(aptOutputDir, variant.dirName) 
    println "****************************" 
    println "variant: ${variant.name}" 
    println "manifest: ${variant.processResources.manifestFile}" 
    println "aptOutput: ${aptOutput}" 
    println "****************************" 

    android.sourceSets[getSourceSetName(variant)].java.srcDirs+= aptOutput.getPath() 

    variant.javaCompile.options.compilerArgs += [ 
      '-processorpath', configurations.apt.getAsPath(), 
      '-AandroidManifestFile=' + variant.processResources.manifestFile, 
      '-s', aptOutput 
    ] 

    variant.javaCompile.source = variant.javaCompile.source.filter { p -> 
     return !p.getPath().startsWith(aptOutputDir.getPath()) 
    } 

    variant.javaCompile.doFirst { 
     aptOutput.mkdirs() 
    } 
} 

Quando si costruisce i liberi varianti, il processore annotazioni viene eseguito come indicato dal seguente nell'output Gradle:

Note: Starting AndroidAnnotations annotation processing 

Quando si costruisce il Pro varianti, il processore delle annotazioni non viene eseguito, quindi i riferimenti al codice generato non riescono.

La cosa curiosa di ciò è che ho trovato (davvero per caso) se rimuovo lo packageName "com.MyCompany.MyApp.Pro" dallo script .... il processore delle annotazioni viene eseguito e verrà creato correttamente. Devo aggiornare il nome del pacchetto per Google Play.

Quando si cerca in studio Android, si può vedere che l'apt (lo strumento di elaborazione di annotazione) sta mostrando la versione Pro ad essere attiva anche quando ho la FreeDebug variante costruzione selezionato. Non sono sicuro che questo sia indicativo di un problema o se questo è solo un problema con la versione beta di Android Studio (versione Android Studio: 0.2.13). Quindi prendilo con un granello di sale.

Build Folders in Android Studio

Sono nuovo al sistema di compilazione Gradle ma ho pensato mi è stato sempre il blocco di esso. Ho esaminato lo script più e più volte e non vedo perché il processore delle annotazioni non è in esecuzione per la variante pro. Oltre a eseguire il wrapper con gli argomenti --info e --debug, non so ancora come eseguire il debug di questi problemi.

Ho eseguito l'involucro Gradle con l'uscita -info e -debug ottenere esteso, ma non c'è niente che indica qualsiasi altro errore (o un elemento mancante) fino a raggiungere l'errore causato dalla scomparsa codice generato. Quindi questo mi porta a credere che sia solo il fatto che le androide non vengano eseguite con quella variante che è il problema principale. (Ad esempio, non penso che si tratti di un errore causato da qualcosa a monte e in seguito segnalato erroneamente. Potrei sbagliarmi)

Sono davvero in perdita e sono rimasto bloccato per 2 giorni.

risposta

12

Sono stato in grado di risolvere il problema. Dopo aver osservato un po 'di più l'output -info del wrapper gradle, ho scoperto che AndroidAnnotations stava tentando di eseguire. L'output dell'errore NON era nell'ordine corretto poiché il messaggio di elaborazione delle annotazioni veniva DOPO gli errori causati dal riferimento al codice inesistente (che non esisteva perché l'elaborazione delle annotazioni falliva).

Ecco il log:

:MyCompany:compileProDebug 
....\src\main\java\com\MyCompany\MyApp\Activities\activityMain.java:14: error: cannot find symbol 
import com.MyCompany.MyApp.Notifications.NotificationSetupActivity_; 
               ^
    symbol: class NotificationSetupActivity_ 
    location: package com.MyCompany.MyApp.Notifications 
....\src\main\java\com\MyCompany\MyApp\Activities\activityMain.java:24: error: cannot find symbol 
import com.MyCompany.MyApp.FantasyScores.ActivityScores_; 
               ^
    symbol: class ActivityScores_ 
    location: package com.MyCompany.MyApp.Scores 
....\src\main\java\com\MyCompany\MyApp\Activities\activityMain.java:32: error: cannot find symbol 
import com.MyCompany.MyApp.Team.activityTeamSelect_; 
            ^
    symbol: class activityTeamSelect_ 
    location: package com.MyCompany.MyApp.Team 
Note: Starting AndroidAnnotations annotation processing 
Note: AndroidManifest.xml file found: ....\build\manifests\pro\debug\AndroidManifest.xml 
error: The generated com.MyCompany.MyAppPro.R class cannot be found 
Note: Time measurements: [Whole Processing = 190 ms], [Extract Manifest = 129 ms], [Extract Annotations = 49 ms], 
....\src\main\java\com\MyCompany\MyApp\Activities\activityMain.java:14: error: cannot find symbol 
import com.MyCompany.MyApp.Notifications.NotificationSetupActivity_; 

Le linee importanti sono questi:

Nota: AndroidAnnotations di iniziare la lavorazione di annotazione

Nota: AndroidManifest.xml file trovato: .... \ build \ manifests \ pro \ debug \ AndroidManifest.xml

errore: Th e generato classe com.MyCompany.MyAppPro.R non può essere trovato

Questi avrebbe dovuto essere prima nel log degli errori come il processore annotazioni viene eseguito prima della fase di compilazione completa, ma per qualche motivo sono stati sepolti in profondità (forse un problema di svuotamento nel processore androidannotations ??)

In ogni caso, la terza riga in cui non è possibile trovare la chiave com.MyCompany.MyAppPro.R è la chiave. Le risorse sono in realtà in com.MyCompany.MyApp.R (no Pro). Dopo aver scavato un po ', ho trovato this post che indica che questo è un problema noto con AndroidAnnotations.

Sono stato in grado di risolvere il problema aggiungendo il parametro '-AresourcePackageName=MyBasePackageName', allo script di compilazione. NOTA: funziona solo se si utilizza l'istantanea 3.0. L'ultima versione rilasciata di AndroidAnnotations non supporta l'opzione -AresourcePackageName.

Dopo aver aggiunto il parametro, tutte le varianti vengono compilate correttamente.

sezione

I compilerArgs dello script di build appare come segue:

variant.javaCompile.options.compilerArgs += [ 
     '-processorpath', configurations.apt.getAsPath(), 
     '-AandroidManifestFile=' + variant.processResources.manifestFile, 
     '-AresourcePackageName=MyBasePackageName', 
     '-s', aptOutput 
] 

Speriamo che questo aiuterà gli altri a evitare questo problema in futuro.

+0

Grazie per aver condiviso la soluzione. – ruX

+0

Ottimo! Grazie! C'è un modo per inserire il nome del pacchetto di base a livello di programmazione? –

+0

Indietro in ottobre ho guardato brevemente per vedere se potevo farlo. Non era una cosa completamente ovvia e non l'ho approfondito molto perché avevo una tempistica ristretta. Dovrebbe teoricamente essere in grado di tirarlo dentro, ma non so fuori mano come farlo. –

Problemi correlati