2013-08-21 6 views
10

Solo poche settimane fa ho avuto la seguente questione: How to replace a string for a buildvariant with gradle?Sostituzione di una stringa in AndroidManifest.xml per un buildvariant non funziona per Gradle Android Plugin versione> 0.5.4

ho anche risposto alla domanda da solo .

Tutto funziona fino ad ora: mi sono appena reso conto che il mio compito di copia non funziona più. Ho trascorso alcune ore sul problema fino a quando ho capito che dipende dalla versione del plugin Android Gradle: Tutto fino a 0.5.4 funziona bene. Per le versioni superiori non entrerò nel mio compito di copia.

Ecco l'output della console:

// gradle android plugin version: 0.5.6 and 0.5.5 --> copy tas doesn't work 
:etscanner:prepareFlavor1Flavor1ReviewDependencies 
:etscanner:compileFlavor1Flavor1ReviewAidl 
:etscanner:generateFlavor1Flavor1ReviewBuildConfig 
:etscanner:mergeFlavor1Flavor1ReviewAssets 
:etscanner:compileFlavor1Flavor1ReviewRenderscript 
:etscanner:mergeFlavor1Flavor1ReviewResources 
:etscanner:processFlavor1Flavor1ReviewManifest 
:etscanner:processFlavor1Flavor1ReviewResources 
:etscanner:compileFlavor1Flavor1ReviewNote: Some input files use or override a d 
eprecated API. 
Note: Recompile with -Xlint:deprecation for details. 
Note: <path>.DetailAdapter 
.java uses unchecked or unsafe operations. 
Note: Recompile with -Xlint:unchecked for details. 

:etscanner:dexFlavor1Flavor1Review 
:etscanner:processFlavor1Flavor1ReviewJavaRes UP-TO-DATE 
:etscanner:validateFlavor1Flavor1Signing 
:etscanner:packageFlavor1Flavor1Review 
:etscanner:zipalignFlavor1Flavor1Review 

// gradle android plugin version: 0.5.4 --> copy task work 
:etscanner:prepareFlavor1Flavor1ReviewDependencies 
:etscanner:compileFlavor1Flavor1ReviewAidl 
:etscanner:generateFlavor1Flavor1ReviewBuildConfig 
:etscanner:mergeFlavor1Flavor1ReviewAssets 
:etscanner:compileFlavor1Flavor1ReviewRenderscript 
:etscanner:mergeFlavor1Flavor1ReviewResources 
:etscanner:processFlavor1Flavor1ReviewManifest 
...hey you are in the copy task! 
:etscanner:processFlavor1Flavor1ReviewResources 
:etscanner:compileFlavor1Flavor1ReviewNote: Some input files use or override a d 
eprecated API. 
Note: Recompile with -Xlint:deprecation for details. 
Note: <path>DetailAdapter 
.java uses unchecked or unsafe operations. 
Note: Recompile with -Xlint:unchecked for details. 

:etscanner:dexFlavor1Flavor1Review 
:etscanner:processFlavor1Flavor1ReviewJavaRes UP-TO-DATE 
:etscanner:validateFlavor1Flavor1Signing 
:etscanner:packageFlavor1Flavor1Review 
:etscanner:zipalignFlavor1Flavor1Review 
:etscanner:assembleFlavor1Flavor1Review 

E 'davvero una cosa strana ... Qualcuno ha un'idea di come risolvere questo problema?

UPDATE 1 2013-08-23

Il mio file build.gradle:

buildscript { 
    repositories { 
     // maven central repo doesn't work with gradle android plugin version 0.5.+ 
     // error message is describe in this post: 
     // https://plus.google.com/117954254390243608387/posts/RVBjoDMkLV5 
     //mavenCentral() 
     maven { 
      url 'http://nexus/content/groups/public/' 
     } 
    } 
    dependencies { 
     classpath 'com.android.tools.build:gradle:0.5.4' 
     // copy task doesn't work for following versions: 
     //classpath 'com.android.tools.build:gradle:0.5.5' 
     //classpath 'com.android.tools.build:gradle:0.5.6' 
     //classpath 'com.android.tools.build:gradle:0.5.+' 
    } 
} 

apply plugin: 'android' 

dependencies { 
    compile 'com.android.support:support-v4:13.0.+' // support lib 
    //compile 'com.actionbarsherlock:actionbarsherlock:[email protected]' 
    compile project(':libraries:actionbarsherlock') 
    compile project(':libraries:google-play-services_lib') 
} 

android { 
    compileSdkVersion 17 
    buildToolsVersion "17.0.0" 

    defaultConfig { 
     minSdkVersion 8 
     targetSdkVersion 17 
     versionName = "2.3" 
     versionCode = 4 
    } 

    // SIGN CONFIGS 
    signingConfigs { 
     flavor1 { 
      storeFile file("keystore/myKeystore.keystore") 
      storePassword = "store_password" 
      keyAlias = "alias" 
      keyPassword = "key_password" 
     } 
     flavor2 { 
      storeFile file("keystore/myKeystore.keystore") 
      storePassword = "store_password" 
      keyAlias = "alias" 
      keyPassword = "key_password" 
     } 
     debug { 
      storeFile file("keystore/debug.keystore") 
      storePassword = "android" 
      keyAlias = "androiddebugkey" 
      keyPassword = "android" 
     } 

    } 

    // FLAVORS 
    productFlavors { 
     flavor1 { 
      packageName 'myPackageName' 
      signingConfig signingConfigs.flavor1 
     } 
     flavor2 { 
      packageName 'myPackageName' 
      signingConfig signingConfigs.flavor2 
     } 
    } 

    // BUILDTYPES 
    buildTypes { 
     falvor1Review { 
      versionNameSuffix = versionNameSuffixOfReviewVersion 
      signingConfig signingConfigs.flavor1 
     } 
     flavor2Review { 
      versionNameSuffix = versionNameSuffixOfReviewVersion 
      signingConfig signingConfigs.flavor2 
     } 

     debug { 
      packageNameSuffix ".debug" 
      versionNameSuffix = versionNameSuffixOfReviewVersion 
      signingConfig signingConfigs.debug 
     } 
    } 

    // Override Data in Manifest 
    android.applicationVariants.each { variant -> 
     variant.processManifest.doLast { 
      copy { 
       // *** SET COPY PATHS *** 
       try { 
        from("${buildDir}/manifests") { 
         //println "from: ${buildDir}/manifests" 
         include "${variant.dirName}/AndroidManifest.xml" 
         //println "included: ${variant.dirName}/AndroidManifest.xml" 
        } 
       } catch (e) { 
        println "error: " + e 
       } 

       into("${buildDir}/manifests/${variant.name}") 
       //println "into (neues Manifest): ${buildDir}/manifests/${variant.name}" 

       // *** DEFINE VARS *** 
       def brandVersion = variant.buildType.name 
       def brandVersionString = brandVersion.toString() 
       def appName = "empty" 

       // *** SET APP NAME *** 
       if (brandVersionString.contains("flavor1")) { 
        appName = "my app name for flavor 1" 
       } else if (brandVersionString.contains("flavor2")) { 
        appName = "my app name for flavor 2" 
       } 

       println "...hey you are in the copy task" 
       // *** REPLACE LINES IN MANIFEST *** 
       // --- add appName 
       filter { 
        String line -> 
         line.replaceAll("<application android:allowBackup=\"true\" android:icon=\"@drawable/ic_launcher\" android:label=\"todo\" android:theme=\"@style/AppTheme\">", 
           "<application android:allowBackup=\"true\" android:icon=\"@drawable/ic_launcher\" android:label=\"" + appName + "\" android:theme=\"@style/AppTheme\">"); 
       } 
      } 
     } 

     // *** SET PATH TO NEW MANIFEST *** 
     variant.processResources.manifestFile = file("${buildDir}/manifests/${variant.name}/${variant.dirName}/AndroidManifest.xml") 
     //println "newManifest: ${buildDir}/manifests/${variant.name}/${variant.dirName}/AndroidManifest.xml" 
    } 
} 

UPDATE 2 2013-08-23

Ieri ho avuto un altro strano comportamento di AS 0.2.5, ha creato alcune build davvero strane: Come vedi nel mio filtro la mia appName precedente nel Manifesto è "todo":

<application 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="todo" 
    android:theme="@style/AppTheme"> 

Quando ho creato la build, l'appName nell'app era quella giusta. Ma in Avvio applicazioni e in Impostazioni/App è stato mostrato "todo" come appName.

Dopo aver creato il progetto in AS 0.2.0, tutto funziona correttamente.

+0

senza sapere come è stato creato il vostro compito e la configurazione, sta andando a essere difficile da eseguire il debug. –

+0

Hey Xav, scusate il mio primo post (http: // StackOverflow.it/questions/17465353/how-to-replace-a-string-per-a-buildvariant-con-gradle-in-android-studio) basterebbe sapere come viene creato il mio compito. Modifica il mio post e aggiungo il file build.gradle completo. – owe

+0

Ho aggiornato AS a 0.2.6 -> ho ancora lo stesso problema :( – owe

risposta

6

Ho avuto lo stesso problema e ho letto le note di rilascio per 0.5.5 dove ho trovato la risposta.

"accesso al contenitore varianti non forzare la creazione dell'attività. Ciò significa android.[application|Library|Test]Variants sarà vuoto durante la fase di valutazione. Per usarlo, utilizzare .all anziché .each"

+0

Ottimo! Questo ha risolto il mio problema! – owe

+1

A chi arriva qui, questo ha risolto il mio problema: http://stackoverflow.com/a/27305242/913275 – Migore

0

Il codice seguente può essere posizionata nel blocco android nella build di gradle.

android { 

... 

    buildTypes { 

    ... 

    applicationVariants.all { variant -> 
     def flavor = variant.productFlavors[0].name 
     def flavorPackageName = variant.productFlavors[0].applicationId 
     variant.processManifest.doLast { 
      println("configuring AndroidManifest.xml for " + flavor); 
      copy { 
       from("${buildDir}/intermediates/manifests") { 
        include "${variant.dirName}/AndroidManifest.xml" 
       } 
       into("${buildDir}/intermediates/filtered_manifests") 
      } 

      def manifestFile = new File("${buildDir}/intermediates/filtered_manifests/${variant.dirName}/AndroidManifest.xml") 
      def content = manifestFile.getText() 
      def updatedContent = content.replaceAll("STRING_TO_BE_REPLACED", "NEW_STRING") 
      manifestFile.write(updatedContent) 
     } 
     variant.processResources.manifestFile = new File("${buildDir}/intermediates/filtered_manifests/${variant.dirName}/AndroidManifest.xml") 
    } 
} 
2

Se vuoi provare la soluzione di Alécio e hanno warning di deprecazione su una nuova versione di Gradle, come ad esempio

Avviso [Progetto::] variant.getProcessManifest() è deprecato. Chiama su uno di variant.getOutputs().

è necessario utilizzare 'variant.outputs.each {uscita ->' per scorrere ogni uscita, vedere il codice qui sotto

applicationVariants.all { variant -> 
    def flavor = variant.productFlavors[0].name 
    def flavorPackageName = variant.productFlavors[0].applicationId 
    variant.outputs.each { output -> 
     output.processManifest.doLast { 
      println("configuring AndroidManifest.xml for " + flavor); 
      copy { 
       from("${buildDir}/intermediates/manifests") { 
        include "${variant.dirName}/AndroidManifest.xml" 
       } 
       into("${buildDir}/intermediates/filtered_manifests") 
      } 

      def manifestFile = new File("${buildDir}/intermediates/filtered_manifests/${variant.dirName}/AndroidManifest.xml") 
      def content = manifestFile.getText() 
      def updatedContent = content.replaceAll("STRING_TO_BE_REPLACED", "NEW_STRING") 
      manifestFile.write(updatedContent) 
     } 
     output.processResources.manifestFile = new File("${buildDir}/intermediates/filtered_manifests/${variant.dirName}/AndroidManifest.xml") 
    } 
} 
Problemi correlati