Sök…


Introduktion

Gradle är ett JVM-baserat build-system som gör det möjligt för utvecklare att skriva skript på hög nivå som kan användas för att automatisera processen för kompilering och applikationsproduktion. Det är ett flexibelt plugin-baserat system som låter dig automatisera olika aspekter av byggprocessen; inklusive att sammanställa och signera en .jar , ladda ner och hantera externa beroenden, injicera fält i AndroidManifest eller använda specifika SDK-versioner.

Syntax

  • apply plugin : Plugins som bör användas normalt bara 'com.android.application' eller 'com.android.library' .

  • android : Huvudkonfigurationen för din app

    • compileSdkVersion : kompilera SDK-versionen
    • buildToolsVersion : versionen för build-verktyg
    • defaultConfig : Standardinställningarna som kan skrivas över av smaker och buildtyper
      • applicationId : Det applikations-id som du använder t.ex. i PlayStore mestadels samma som ditt paketnamn
      • minSdkVersion : Den minimala SDK-versionen
      • targetSdkVersion : SDK-versionen du sammanställer mot (ska alltid vara den nyaste)
      • versionCode : Det interna versionCode som måste vara större för varje uppdatering
      • versionName : versionName användaren kan se på sidan med appdetaljer
    • buildTypes : Se någon annanstans (TODO)
  • dependencies : Appens maven eller lokala beroenden

    • compile ett enda beroende
    • testCompile : ett beroende för enheten eller integrationstester

Anmärkningar

Se även

Gradle for Android - Utökad dokumentation:

Det finns en annan tagg där du kan hitta fler ämnen och exempel om användning av gradle i Android.
http://www.riptutorial.com/topic/2092

En grundläggande build.gradle-fil

Detta är ett exempel på en standard build.gradle fil i en modul.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion '25.0.3'

    signingConfigs {
        applicationName {
            keyAlias 'applicationName'
            keyPassword 'password'
            storeFile file('../key/applicationName.jks')
            storePassword 'keystorePassword'
        }
    }
    defaultConfig {
        applicationId 'com.company.applicationName'
        minSdkVersion 14
        targetSdkVersion 25
        versionCode 1
        versionName '1.0'
        signingConfig signingConfigs.applicationName
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support:design:25.3.1'

    testCompile 'junit:junit:4.12'
}

DSL (domänspecifikt språk)

Varje block i filen ovan kallas ett DSL (domänspecifikt språk).


plugins

Den första raden, apply plugin: 'com.android.application' , tillämpar Android-plugin för Gradle på build och gör android {} -blocket tillgängligt för att förklara Android-specifika build-alternativ.

För en Android-applikation :

apply plugin: 'com.android.application'

För ett Android-bibliotek :

apply plugin: 'com.android.library'

Förstå DSL: erna i exemplet ovan

Den andra delen, android {...} -blocket, är Android DSL som innehåller information om ditt projekt.

Du kan till exempel ställa in compileSdkVersion som anger Android API-nivån, som bör användas av Gradle för att kompilera din app.
defaultConfig innehåller standardvärdena för ditt manifest. Du kan override dem med produktsmak .

Du kan hitta mer info i dessa exempel:


beroenden

dependencies blocket definieras utanför android {...} : Det betyder att det inte definieras av Android-plugin men det är standard Gradle.
dependencies blocket anger vilka externa bibliotek (vanligtvis Android-bibliotek, men Java-bibliotek är också giltiga) du vill inkludera i din app. Gradle hämtar automatiskt dessa beroenden för dig (om det inte finns någon lokal kopia tillgänglig), du behöver bara lägga till liknande compile när du vill lägga till ett annat bibliotek.

Låt oss titta på en av de rader som finns här:

compile 'com.android.support:design:25.3.1'

Denna linje säger i princip

lägg till ett beroende av Android-supportdesignbiblioteket till mitt projekt.

Gradle kommer att se till att biblioteket laddas ner och finns så att du kan använda det i din app, och dess kod kommer också att inkluderas i din app.

Om du är bekant med Maven är den här syntaxen GroupId , en kolon, ArtifactId , en annan kolon, sedan den version av beroendet du vill inkludera, vilket ger dig full kontroll över versioneringen.

Det är möjligt att specificera artefaktversioner med plustecknet (+), men bästa praxis är att undvika att göra det; Det kan leda till problem om biblioteket uppdateras med att bryta ändringar utan din vetskap, vilket sannolikt skulle leda till kraschar i din app.

Du kan lägga till olika slags beroenden:

En särskild uppmärksamhet bör ägnas åt de vanliga beroenden .

Du kan hitta mer information i det här ämnet.

Obs om -v7 i appcompat-v7

compile 'com.android.support:appcompat-v7:25.3.1'

Detta betyder helt enkelt att detta bibliotek ( appcompat ) är kompatibelt med Android API nivå 7 och framåt.

Obs om junit: junit: 4.12

Detta är Testberoende för enhetstestning.


Ange beroenden specifika för olika byggkonfigurationer

Du kan ange att ett beroende endast ska användas för en viss byggkonfiguration eller att du kan definiera olika beroenden för byggtyperna eller produktsmakarna (t.ex. debug, test eller release) genom att använda debugCompile , testCompile eller releaseCompile istället för den vanliga compile .

Detta är användbart för att hålla test- och felsökningsberoende utanför din release-version, vilket kommer att hålla din release- APK så smal som möjligt och hjälpa till att se till att felsökningsinformation inte kan användas för att få intern information om din app.


signingConfig

signingConfig låter dig konfigurera din Gradle så att den innehåller information om keystore och säkerställer att APK byggd med dessa konfigurationer är signerad och redo för Play Store-släpp.

Här kan du hitta ett särskilt ämne .

Obs : Det rekommenderas dock inte att behålla signaturuppgifterna i din Gradle-fil. För att ta bort signeringskonfigurationerna, signingConfigs bara signingConfigs delen.
Du kan ange dem på olika sätt:

Se detta ämne för mer information: Signera APK utan att avslöja lösenordet för keystore .


Du kan hitta mer information om Gradle for Android i det dedikerade Gradle-ämnet .

Definiera produktsmaker

Produktsmakar definieras i build.gradle filen inuti android { ... } -blocket enligt nedan.

...
android {
    ...
    productFlavors {
        free {
            applicationId "com.example.app.free"
            versionName "1.0-free"
        }
        paid {
            applicationId "com.example.app.paid"
            versionName "1.0-paid"
        }
    }
}

Genom att göra detta har vi nu ytterligare två produktsmaker: free och paid . Var och en kan ha sin egen specifika konfiguration och attribut. Till exempel har båda våra nya smaker en separat applicationId och versionName än vår nuvarande main smak (finns som standard, så inte visas här).

Lägga till produktsmakspecifika beroenden

Beroenden kan läggas till för en specifik produktsmak , liknande hur de kan läggas till för specifika byggkonfigurationer.

För detta exempel antar vi att vi redan har definierat två produktsmaker som kallas free och paid (mer om att definiera smaker här ).
Vi kan sedan lägga till AdMob-beroende för den free smaken, och Picasso-biblioteket för den paid så:

android {
    ...

    productFlavors {
        free {
            applicationId "com.example.app.free"
            versionName "1.0-free"
        }
        paid {
            applicationId "com.example.app.paid"
            versionName "1.0-paid"
        }
    }
}

...
dependencies {
    ...
    // Add AdMob only for free flavor
    freeCompile 'com.android.support:appcompat-v7:23.1.1'
    freeCompile 'com.google.android.gms:play-services-ads:8.4.0'
    freeCompile 'com.android.support:support-v4:23.1.1'

    // Add picasso only for paid flavor
    paidCompile 'com.squareup.picasso:picasso:2.5.2'
} 
...

Lägga till produktsmakspecifika resurser

Resurser kan läggas till för en specifik produktsmak .

För detta exempel antar vi att vi redan har definierat två produktsmaker som kallas free och paid . För att lägga till produktsmakspecifika resurser skapar vi ytterligare resursmappar bredvid main/res mappen, som vi sedan kan lägga till resurser som vanligt. I det här exemplet definierar vi en sträng, status för varje produktsmak:

/ src / main /res/values/strings.xml

<resources>
    <string name="status">Default</string>
</resources>

/ src / gratis /res/values/strings.xml

<resources>
    <string name="status">Free</string>
</resources>

/ src / betald /res/values/strings.xml

<resources>
    <string name="status">Paid</string>
</resources>

De produktsmak specifika status åsidosätter värdet för status i main smak.

Definiera och använd Build Configuration Fields

BuildConfigField

Gradle tillåter buildConfigField linjer att definiera konstanter. Dessa konstanter kommer att vara tillgängliga under körning som statiska fält i BuildConfig klassen. Detta kan användas för att skapa smaker genom att definiera alla fält i defaultConfig blocket och sedan åsidosätta dem för individuella build-smaker efter behov.

I det här exemplet definieras byggdatumet och flaggas bygget för produktion snarare än test:

android {
    ...
    defaultConfig {
        ...
        // defining the build date
        buildConfigField "long", "BUILD_DATE", System.currentTimeMillis() + "L"
        // define whether this build is a production build
        buildConfigField "boolean", "IS_PRODUCTION", "false"
        // note that to define a string you need to escape it
        buildConfigField "String", "API_KEY", "\"my_api_key\""
    }

    productFlavors {
        prod {
            // override the productive flag for the flavor "prod"
            buildConfigField "boolean", "IS_PRODUCTION", "true"
            resValue 'string', 'app_name', 'My App Name'
        }
        dev {
            // inherit default fields
            resValue 'string', 'app_name', 'My App Name - Dev'
        }
    }
}

Det automatiskt genererade <paketnamnet>. BuildConfig .java i gen-mappen innehåller följande fält baserade på direktivet ovan:

public class BuildConfig {
    // ... other generated fields ...
    public static final long BUILD_DATE = 1469504547000L;
    public static final boolean IS_PRODUCTION = false;
    public static final String API_KEY = "my_api_key";
}

De definierade fälten kan nu användas i appen under körning genom att komma åt den genererade BuildConfig klassen:

public void example() {
    // format the build date
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
    String buildDate = dateFormat.format(new Date(BuildConfig.BUILD_DATE));
    Log.d("build date", buildDate);
    
    // do something depending whether this is a productive build
    if (BuildConfig.IS_PRODUCTION) {
        connectToProductionApiEndpoint();
    } else {
        connectToStagingApiEndpoint();
    }
}

ResValue

resValue i productFlavors skapar ett productFlavors . Det kan vara valfri typ av resurs ( string , dimen , color etc.). Detta liknar att definiera en resurs i rätt fil: t.ex. att definiera sträng i en strings.xml fil. Fördelen är att den som definieras i graden kan modifieras baserat på din produktFlavor / buildVariant. För att komma åt värdet, skriv samma kod som om du åtkomst till en res från resursfilen:

getResources().getString(R.string.app_name)

Det viktiga är att resurser definierade på detta sätt inte kan modifiera befintliga resurser definierade i filer. De kan bara skapa nya resursvärden.


Vissa bibliotek (t.ex. Google Maps Android API) kräver en API-nyckel som tillhandahålls i manifestet som en meta-data . Om olika nycklar behövs för felsökning och produktionsbyggnad, ange en manifest platshållare fylld av Gradle.

I din AndroidManifest.xml fil:

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="${MAPS_API_KEY}"/>

Och ställ sedan in fältet i din build.gradle fil:

android {
    defaultConfig {
        ...
        // Your development key
        manifestPlaceholders = [ MAPS_API_KEY: "AIza..." ]
    }

    productFlavors {
        prod {
            // Your production key
            manifestPlaceholders = [ MAPS_API_KEY: "AIza..." ]
        }
    }
}

Android build-systemet genererar automatiskt ett antal fält och placerar dem i BuildConfig.java . Dessa fält är:

Fält Beskrivning
DEBUG en Boolean anger om appen är i felsökning eller släppläge
APPLICATION_ID en String innehåller applikationens ID (t.ex. com.example.app )
BUILD_TYPE en String innehåller applikationens byggtyp (vanligtvis antingen debug eller release )
FLAVOR en String innehåller den speciella smaken på byggnaden
VERSION_CODE en int innehåller version (build) -nummer.
Detta är samma sak som versionCode i build.gradle eller versionCode i AndroidManifest.xml
VERSION_NAME en String innehåller versionens (build) -namn.
Detta är samma sak som versionName i build.gradle eller versionName i AndroidManifest.xml

Förutom ovanstående, om du har definierat flera smaksdimensioner, kommer varje dimension att ha sitt eget värde. Om du till exempel hade två smaksdimensioner för color och size du också följande variabler:

Fält Beskrivning
FLAVOR_color en String innehåller värdet för "färg" -smaken.
FLAVOR_size en String innehåller värdet för smaken "storlek".

Centralisering av beroenden via filen "dependensions.gradle"

När du arbetar med projekt med flera moduler är det bra att centralisera beroenden på en enda plats snarare än att sprida dem över många build-filer, särskilt för vanliga bibliotek som Android-stödbibliotek och Firebase-bibliotek .

Ett rekommenderat sätt är att separera Gradle build-filer, med en build.gradle per modul, såväl som en i projektroten och en annan för beroenden, till exempel:

root
  +- gradleScript/
  |     dependencies.gradle
  +- module1/
  |     build.gradle
  +- module2/
  |     build.gradle
  +- build.gradle

Sedan kan alla dina beroenden placeras i gradleScript/dependencies.gradle :

ext {
    // Version
    supportVersion = '24.1.0'

    // Support Libraries dependencies
    supportDependencies = [
            design:            "com.android.support:design:${supportVersion}",
            recyclerView:      "com.android.support:recyclerview-v7:${supportVersion}",
            cardView:          "com.android.support:cardview-v7:${supportVersion}",
            appCompat:         "com.android.support:appcompat-v7:${supportVersion}",
            supportAnnotation: "com.android.support:support-annotations:${supportVersion}",
    ]

    firebaseVersion = '9.2.0';

    firebaseDependencies = [
            core:         "com.google.firebase:firebase-core:${firebaseVersion}",
            database:     "com.google.firebase:firebase-database:${firebaseVersion}",
            storage:      "com.google.firebase:firebase-storage:${firebaseVersion}",
            crash:        "com.google.firebase:firebase-crash:${firebaseVersion}",
            auth:         "com.google.firebase:firebase-auth:${firebaseVersion}",
            messaging:    "com.google.firebase:firebase-messaging:${firebaseVersion}",
            remoteConfig: "com.google.firebase:firebase-config:${firebaseVersion}",
            invites:      "com.google.firebase:firebase-invites:${firebaseVersion}",
            adMod:        "com.google.firebase:firebase-ads:${firebaseVersion}",
            appIndexing:  "com.google.android.gms:play-services-appindexing:${firebaseVersion}",
    ];
}

Vilket kan sedan tillämpas från den filen i build.gradle så:

// Load dependencies
apply from: 'gradleScript/dependencies.gradle'

och i module1/build.gradle så:

// Module build file
dependencies {
    // ...
    compile supportDependencies.appCompat
    compile supportDependencies.design
    compile firebaseDependencies.crash
}

En annan metod

Ett mindre ordentligt tillvägagångssätt för att centralisera versioner av bibliotekberoende kan uppnås genom att deklarera versionnumret som en variabel en gång och använda det överallt.

build.gradle till detta i arbetsområdet root build.gradle :

ext.v = [
    supportVersion:'24.1.1',
]

Och i varje modul som använder samma bibliotek lägg till de bibliotek som behövs

compile "com.android.support:support-v4:${v.supportVersion}"
compile "com.android.support:recyclerview-v7:${v.supportVersion}"
compile "com.android.support:design:${v.supportVersion}"
compile "com.android.support:support-annotations:${v.supportVersion}"

Katalogstruktur för smakspecifika resurser

Olika smaker av applikationsbyggnader kan innehålla olika resurser. För att skapa en smakspecifik resurs ska du skapa en katalog med små bokstäverna på din smak i src katalogen och lägga till dina resurser på samma sätt som du normalt skulle göra.

Till exempel, om du hade en smak Development och ville ge en tydlig launcher ikon för det du skulle skapa en katalog src/development/res/drawable-mdpi och innanför den katalogen skapar en ic_launcher.png fil med din utveckling specifik ikon.

Katalogstrukturen ser ut så här:

src/
  main/
    res/
      drawable-mdpi/
        ic_launcher.png  <-- the default launcher icon
  development/
    res/
      drawable-mdpi/
        ic_launcher.png  <-- the launcher icon used when the product flavor is 'Development'

(I detta fall skulle du naturligtvis också skapa ikoner för drawable-hdpi, drawable-xhdpi etc ).

Varför finns det två build.gradle-filer i ett Android Studio-projekt?

<PROJECT_ROOT>\app\build.gradle är specifikt för appmodul .

<PROJECT_ROOT>\build.gradle är en "Top-level build-fil" där du kan lägga till konfigurationsalternativ som är gemensamma för alla delprojekt / moduler.

Om du använder en annan modul i ditt projekt skulle du som ett lokalt bibliotek ha en annan build.gradle fil: <PROJECT_ROOT>\module\build.gradle

I filen på översta nivån kan du ange vanliga egenskaper som buildscript-blocket eller några vanliga egenskaper.

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
       classpath 'com.android.tools.build:gradle:2.2.0'
       classpath 'com.google.gms:google-services:3.0.0'
    }
}

ext {
    compileSdkVersion = 23
    buildToolsVersion = "23.0.1"
}

I app\build.gradle definierar du bara egenskaperna för modulen:

apply plugin: 'com.android.application'


android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion
}

dependencies {
    //.....
}

Utför ett skalskript från gradle

Ett skalskript är ett mycket mångsidigt sätt att utöka din byggnad till i princip allt du kan tänka på.

Som ett exempel, här är ett enkelt skript för att sammanställa protobuf-filer och lägga till resultat-java-filer i källkatalogen för ytterligare sammanställning:

def compilePb() {
    exec {
        // NOTICE: gradle will fail if there's an error in the protoc file...
        executable "../pbScript.sh"
    }
}

project.afterEvaluate {
    compilePb()
}

Skalskriptet 'pbScript.sh' för det här exemplet, som finns i projektets rotmapp:

#!/usr/bin/env bash
pp=/home/myself/my/proto

/usr/local/bin/protoc -I=$pp \
 --java_out=./src/main/java \
  --proto_path=$pp \
 $pp/my.proto \
 --proto_path=$pp \
 $pp/my_other.proto

Felsöka dina Gradle-fel

Följande är ett utdrag från Gradle - Vad är ett utgångsvärde utan noll och hur fixar jag det? , se det för en fullständig diskussion.

Låt oss säga att du utvecklar en applikation och du får något Gradle-fel som verkar som i allmänhet kommer att se ut så.

:module:someTask FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':module:someTask'.
> some message here...  finished with non-zero exit value X
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: Y.ZZ secs

Du söker här på StackOverflow efter ditt problem, och folk säger att rensa och bygga om ditt projekt, eller aktivera MultiDex , och när du försöker det löser det inte problemet.

Det finns sätt att få mer information , men själva Gradle-utgången bör peka på det faktiska felet i de få raderna ovanför det meddelandet mellan: module:someTask FAILED och den senaste :module:someOtherTask som gick. Om du ställer en fråga om ditt fel kan du redigera dina frågor så att du får mer sammanhang till felet.

Så du får ett "utgångsvärde utan noll." Det numret är en bra indikator på vad du bör försöka fixa. Här är några förekommer oftast.

  • 1 är bara en allmän felkod och felet är troligt i Gradle-utgången
  • 2 verkar vara relaterat till överlappande beroenden eller felkonfiguration av projektet.
  • 3 verkar komma från att inkludera för många beroenden eller ett minnesfråga.

De allmänna lösningarna för ovanstående (efter att ha försökt en ren och ombyggnad av projektet) är:

  • 1 - Lös problemet som nämns. I allmänhet är detta ett kompileringstidsfel, vilket betyder att en kodkod i ditt projekt inte är giltig. Detta inkluderar både XML och Java för ett Android-projekt.
  • 2 & 3 - Många svar här säger dig att aktivera multidex . Även om det kan lösa problemet, är det troligtvis en lösning. Om du inte förstår varför du använder det (se länken) behöver du förmodligen inte det. Allmänna lösningar innebär att du minskar ditt överanvändning av biblioteksberoenden (till exempel alla Google Play-tjänster, om du bara behöver använda ett bibliotek, till exempel Kartor eller inloggning).

Ange olika applikations-ID för byggtyper och produktsmaker

Du kan ange olika applikations-ID eller paketnamn för varje buildType eller productFlavor hjälp av applikationsIdSuffix- konfigurationsattributet:

Exempel på att suffixera applicationId för varje buildType :

defaultConfig {
    applicationId "com.package.android"
    minSdkVersion 17
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
}

buildTypes {
    release {
        debuggable false      
    }

    development {
        debuggable true
        applicationIdSuffix ".dev"
    }

    testing {
        debuggable true
        applicationIdSuffix ".qa"
    }
}

Vårt resulterande applicationIds skulle nu vara:

  • com.package.android för release
  • com.package.android. dev för development
  • com.package.android. qa för testing

Detta kan också göras för productFlavors :

productFlavors {
    free {
        applicationIdSuffix ".free"
    }
    paid {
        applicationIdSuffix ".paid"
    }
}

Den resulterande applicationIds skulle vara:

  • com.package.android. gratis för den free smaken
  • com.package.android. betalat för den paid smaken

Signera APK utan att avslöja keystore-lösenordet

Du kan definiera signeringskonfigurationen för att signera apk i build.gradle filen med hjälp av dessa egenskaper:

  • storeFile : keystore-filen
  • storePassword : keystore-lösenordet
  • keyAlias : ett nyckel alias namn
  • keyPassword : Ett nyckelaliaslösenord

I många fall kan du behöva undvika den här typen av information i build.gradle filen.

Metod A: Konfigurera släppsignering med en keystore.properties-fil

Det är möjligt att konfigurera appens build.gradle så att den kommer att läsa informationen om signeringskonfigurering från en egenskaperfil som keystore.properties .

Att ställa in signering så här är fördelaktigt eftersom:

  • Din signaturkonfigurationsinformation är separat från din build.gradle fil
  • Du behöver inte ingripa under signeringsprocessen för att tillhandahålla lösenord för din keystore-fil
  • Du kan enkelt utesluta filen keystore.properties från versionskontroll

keystore.properties en fil som heter keystore.properties i roten till ditt projekt med innehåll som detta (ersätta värdena med ditt eget):

storeFile=keystore.jks
storePassword=storePassword
keyAlias=keyAlias
keyPassword=keyPassword

Nu, i appens build.gradle fil, ställer du in signingConfigs blocket på följande sätt:

android {
...

    signingConfigs {
        release {
            def propsFile = rootProject.file('keystore.properties')
            if (propsFile.exists()) {
                def props = new Properties()
                props.load(new FileInputStream(propsFile))
                storeFile = file(props['storeFile'])
                storePassword = props['storePassword']
                keyAlias = props['keyAlias']
                keyPassword = props['keyPassword']
            }
        }
    }
}

Det är verkligen allt som behövs , men glöm inte att utesluta både din keystore-fil och din keystore.properties fil från versionskontroll .

Ett par saker att notera:

  • storeFile sökvägen som anges i keystore.properties filen ska vara relativt din build.gradle fil. Detta exempel antar att keystore-filen finns i samma katalog som appens build.gradle fil.
  • Detta exempel har filen keystore.properties i roten till projektet. Om du lägger det någon annanstans, se till att du ändrar värdet i rootProject.file('keystore.properties') till din plats, relativt roten till ditt projekt.

Metod B: Genom att använda en miljövariabel

Detsamma kan också uppnås utan en egenskapsfil, vilket gör lösenordet svårare att hitta:

android {

  signingConfigs {
    release {
        storeFile file('/your/keystore/location/key')
        keyAlias 'your_alias'
        String ps = System.getenv("ps")
        if (ps == null) {
             throw new GradleException('missing ps env variable')
        }
        keyPassword ps
        storePassword ps
    }
}

"ps" kan vara global, men ett säkrare tillvägagångssätt kan vara genom att bara lägga till den i skalet i Android Studio.
I Linux kan detta göras genom att redigera Android Studios Desktop Entry

Exec=sh -c "export ps=myPassword123 ; /path/to/studio.sh"

Du kan hitta mer information i det här ämnet .

Versionera dina builds via "version.properties" -filen

Du kan använda Gradle för att automatiskt öka din paketversion varje gång du bygger den. Så här skapar du en version.properties fil i samma katalog som din build.gradle med följande innehåll:

VERSION_MAJOR=0
VERSION_MINOR=1
VERSION_BUILD=1

(Ändra värdena för major och minor enligt vad som är lämpligt). Sedan i din build.gradle lägga till följande kod i android avsnitt:

// Read version information from local file and increment as appropriate
def versionPropsFile = file('version.properties')
if (versionPropsFile.canRead()) {
  def Properties versionProps = new Properties()

  versionProps.load(new FileInputStream(versionPropsFile))

  def versionMajor = versionProps['VERSION_MAJOR'].toInteger()
  def versionMinor = versionProps['VERSION_MINOR'].toInteger()
  def versionBuild = versionProps['VERSION_BUILD'].toInteger() + 1

  // Update the build number in the local file
  versionProps['VERSION_BUILD'] = versionBuild.toString()
  versionProps.store(versionPropsFile.newWriter(), null)

  defaultConfig {
    versionCode versionBuild
    versionName "${versionMajor}.${versionMinor}." + String.format("%05d", versionBuild)
  }
}

Informationen kan nås i Java som en sträng BuildConfig.VERSION_NAME för hela {major}. {Minor}. {Build} BuildConfig.VERSION_CODE och som ett heltal BuildConfig.VERSION_CODE för bara build-numret.

Ändra apk-namn på utgång och lägg till versionnamn:

Det här är koden för att ändra utdatafilerens namn (.apk). Namnet kan konfigureras genom att tilldela ett annat värde till newName

android {

    applicationVariants.all { variant ->
        def newName = "ApkName";
        variant.outputs.each { output ->
            def apk = output.outputFile;

            newName += "-v" + defaultConfig.versionName;
            if (variant.buildType.name == "release") {
                newName += "-release.apk";
            } else {
                newName += ".apk";
            }
            if (!output.zipAlign) {
                newName = newName.replace(".apk", "-unaligned.apk");
            }

            output.outputFile = new File(apk.parentFile, newName);
            logger.info("INFO: Set outputFile to " 
                        + output.outputFile 
                        + " for [" + output.name + "]");
        }
    }
}

Inaktivera bildkomprimering för en mindre APK-filstorlek

Om du optimerar alla bilder manuellt, inaktivera APT Cruncher för en mindre APK-filstorlek.

android {
    
    aaptOptions {
        cruncherEnabled = false
    }
}

Aktivera Proguard med hjälp av gradle

För att aktivera Proguard-konfigurationer för din applikation måste du aktivera den i din modulnivågradfil. Du måste ställa in värdet på minifyEnabled till true .

buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

Ovanstående kod kommer att tillämpa dina Proguard-konfigurationer som finns i standard-SDK: n i kombination med "proguard-rules.pro" -filen på din modul till din släppta apk.

Aktivera experimentellt NDK-pluginstöd för Gradle och AndroidStudio

Aktivera och konfigurera den experimentella Gradle-plugin för att förbättra AndroidStudios NDK-stöd. Kontrollera att du uppfyller följande krav:

  • Gradle 2.10 (för detta exempel)
  • Android NDK r10 eller senare
  • Android SDK med build-verktyg v19.0.0 eller senare

Konfigurera MyApp / build.gradle-filen

Redigera linjen dependences.classpath i build.gradle från t.ex.

classpath 'com.android.tools.build:gradle:2.1.2'

till

classpath 'com.android.tools.build:gradle-experimental:0.7.2'

(v0.7.2 var den senaste versionen i skrivande stund. Kontrollera själv den senaste versionen och anpassa din linje därefter)

Build.gradle-filen ska se ut så här:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle-experimental:0.7.2'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

Konfigurera MyApp / app / build.gradle-fil

Redigera build.gradle-filen så att den ser ut som följande exempel. Dina versionnummer kan se annorlunda ut.

apply plugin: 'com.android.model.application'

model {
    android {
        compileSdkVersion 19
        buildToolsVersion "24.0.1"

        defaultConfig {
            applicationId "com.example.mydomain.myapp"
            minSdkVersion.apiLevel 19
            targetSdkVersion.apiLevel 19
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles.add(file('proguard-android.txt'))
            }
        }
        ndk {
            moduleName "myLib"
            
            /* The following lines are examples of a some optional flags that 
               you may set to configure your build environment
            */ 
            cppFlags.add("-I${file("path/to/my/includes/dir")}".toString())
            cppFlags.add("-std=c++11")
            ldLibs.addAll(['log', 'm'])
            stl = "c++_static"
            abiFilters.add("armeabi-v7a")
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}

Synkronisera och kontrollera att det inte finns några fel i Gradle-filerna innan du fortsätter.

Testa om plugin är aktiverat

Se först till att du har laddat ner Android NDK-modulen. Skapa sedan en ny app i AndroidStudio och lägg till följande i ActivityMain-filen:

public class MainActivity implements Activity {
    onCreate() {
        // Pregenerated code. Not important here
    }
    static {
        System.loadLibrary("myLib");
    }
    public static native String getString();
}

getString() bör markeras med rött och säga att motsvarande JNI-funktion inte kunde hittas. Håll musen över funktionssamtalet tills en röd glödlampa visas. Klicka på lampan och välj create function JNI_... Detta bör generera en myLib.c-fil i myApp / app / src / main / jni-katalogen med rätt JNI-funktionssamtal. Det borde se ut så här:

#include <jni.h>

JNIEXPORT jstring JNICALL 
Java_com_example_mydomain_myapp_MainActivity_getString(JNIEnv *env, jobject instance)     
{
    // TODO

    return (*env)->NewStringUTF(env, returnValue);
}

Om det inte ser ut så har plugin inte korrekt konfigurerats eller NDK har inte laddats ner

Visa alla uppgraderingsprojektuppgifter

gradlew tasks -- show all tasks

 

Android tasks
-------------
androidDependencies - Displays the Android dependencies of the project.
signingReport - Displays the signing info for each variant.
sourceSets - Prints out all the source sets defined in this project.

Build tasks
-----------
assemble - Assembles all variants of all applications and secondary packages.
assembleAndroidTest - Assembles all the Test applications.
assembleDebug - Assembles all Debug builds.
assembleRelease - Assembles all Release builds.
build - Assembles and tests this project.
buildDependents - Assembles and tests this project and all projects that depend on it.
buildNeeded - Assembles and tests this project and all projects it depends on.
classes - Assembles main classes.
clean - Deletes the build directory.
compileDebugAndroidTestSources
compileDebugSources
compileDebugUnitTestSources
compileReleaseSources
compileReleaseUnitTestSources
extractDebugAnnotations - Extracts Android annotations for the debug variant into the archive file
extractReleaseAnnotations - Extracts Android annotations for the release variant into the archive file
jar - Assembles a jar archive containing the main classes.
mockableAndroidJar - Creates a version of android.jar that's suitable for unit tests.
testClasses - Assembles test classes.

Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
wrapper - Generates Gradle wrapper files. [incubating]

Documentation tasks
-------------------
javadoc - Generates Javadoc API documentation for the main source code.

Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'LeitnerBoxPro'.
components - Displays the components produced by root project 'LeitnerBoxPro'. [incubating]
dependencies - Displays all dependencies declared in root project 'LeitnerBoxPro'.
dependencyInsight - Displays the insight into a specific dependency in root project 'LeitnerBoxPro'.
help - Displays a help message.
model - Displays the configuration model of root project 'LeitnerBoxPro'. [incubating]
projects - Displays the sub-projects of root project 'LeitnerBoxPro'.
properties - Displays the properties of root project 'LeitnerBoxPro'.
tasks - Displays the tasks runnable from root project 'LeitnerBoxPro' (some of the displayed tasks may belong to subprojects)
.

Install tasks
-------------
installDebug - Installs the Debug build.
installDebugAndroidTest - Installs the android (on device) tests for the Debug build.
uninstallAll - Uninstall all applications.
uninstallDebug - Uninstalls the Debug build.
uninstallDebugAndroidTest - Uninstalls the android (on device) tests for the Debug build.
uninstallRelease - Uninstalls the Release build.

Verification tasks
------------------
check - Runs all checks.
connectedAndroidTest - Installs and runs instrumentation tests for all flavors on connected devices.
connectedCheck - Runs all device checks on currently connected devices.
connectedDebugAndroidTest - Installs and runs the tests for debug on connected devices.
deviceAndroidTest - Installs and runs instrumentation tests using all Device Providers.
deviceCheck - Runs all device checks using Device Providers and Test Servers.
lint - Runs lint on all variants.
lintDebug - Runs lint on the Debug build.
lintRelease - Runs lint on the Release build.
test - Run unit tests for all variants.
testDebugUnitTest - Run unit tests for the debug build.
testReleaseUnitTest - Run unit tests for the release build.

Other tasks
-----------
assembleDefault
clean
jarDebugClasses
jarReleaseClasses
transformResourcesWithMergeJavaResForDebugUnitTest
transformResourcesWithMergeJavaResForReleaseUnitTest

Radera "ojusterad" apk automatiskt

Om du inte behöver automatiskt genererade apk-filer med unaligned suffix (som du förmodligen inte gör) kan du lägga till följande kod i build.gradle filen:

// delete unaligned files
android.applicationVariants.all { variant ->
  variant.assemble.doLast {
    variant.outputs.each { output ->
        println "aligned " + output.outputFile
        println "unaligned " + output.packageApplication.outputFile

        File unaligned = output.packageApplication.outputFile;
        File aligned = output.outputFile
        if (!unaligned.getName().equalsIgnoreCase(aligned.getName())) {
            println "deleting " + unaligned.getName()
            unaligned.delete()
        }
    }
  }
}

från här

Ignorerar byggvarianten

Av vissa anledningar kanske du vill ignorera dina byggvarianter. Till exempel: du har "hålig" produktsmak och du använder den bara för felsökningsändamål, till exempel enhet / instrumenttest.

Låt oss ignorera mockRelease- variant från vårt projekt. Öppna filen build.gradle och skriv:

    // Remove mockRelease as it's not needed.
    android.variantFilter { variant ->
        if (variant.buildType.name.equals('release') && variant.getFlavors().get(0).name.equals('mock')) {
            variant.setIgnore(true);
        }
    }

Se beroende träd

Använd uppgiftsberoenden. Beroende på hur dina moduler är ./gradlew dependencies kan det vara antingen ./gradlew dependencies eller för att se beroenden för användning av modul-app ./gradlew :app:dependencies

Exemplet efter build.gradle-fil

dependencies {
    compile 'com.android.support:design:23.2.1'
    compile 'com.android.support:cardview-v7:23.1.1'

    compile 'com.google.android.gms:play-services:6.5.87'
}

kommer att producera följande graf:

Parallel execution is an incubating feature.
:app:dependencies

------------------------------------------------------------
Project :app
------------------------------------------------------------
. . .
_releaseApk - ## Internal use, do not manually configure ##
+--- com.android.support:design:23.2.1
|    +--- com.android.support:support-v4:23.2.1
|    |    \--- com.android.support:support-annotations:23.2.1
|    +--- com.android.support:appcompat-v7:23.2.1
|    |    +--- com.android.support:support-v4:23.2.1 (*)
|    |    +--- com.android.support:animated-vector-drawable:23.2.1
|    |    |    \--- com.android.support:support-vector-drawable:23.2.1
|    |    |         \--- com.android.support:support-v4:23.2.1 (*)
|    |    \--- com.android.support:support-vector-drawable:23.2.1 (*)
|    \--- com.android.support:recyclerview-v7:23.2.1
|         +--- com.android.support:support-v4:23.2.1 (*)
|         \--- com.android.support:support-annotations:23.2.1
+--- com.android.support:cardview-v7:23.1.1
\--- com.google.android.gms:play-services:6.5.87
     \--- com.android.support:support-v4:21.0.0 -> 23.2.1 (*)

. . .

Här kan du se att projektet direkt inkluderar com.android.support:design version 23.2.1, som i sig kommer com.android.support:support-v4 med version 23.2.1. com.google.android.gms:play-services sig är dock beroende av samma support-v4 men med en äldre version 21.0.0, vilket är en konflikt som upptäcks av gradle.

(*) används när graden hoppar över undertråden eftersom dessa beroenden redan listats tidigare.

Använd gradle.properties för central version / buildconfigurations

Du kan definiera centrala konfigurationsinfo i

eller gör det med root gradle.properties filen

projektstrukturen

root
  +- module1/
  |     build.gradle
  +- module2/
  |     build.gradle
  +- build.gradle
  +- gradle.properties

global inställning för alla undermoduler i gradle.properties

# used for manifest
# todo increment for every release
appVersionCode=19
appVersionName=0.5.2.160726

# android tools settings
appCompileSdkVersion=23
appBuildToolsVersion=23.0.2

användning i en undermodul

apply plugin: 'com.android.application'
android {
    // appXXX are defined in gradle.properties
    compileSdkVersion = Integer.valueOf(appCompileSdkVersion)
    buildToolsVersion = appBuildToolsVersion

    defaultConfig {
        // appXXX are defined in gradle.properties
        versionCode = Long.valueOf(appVersionCode)
        versionName = appVersionName
    }
}

dependencies {
    ...
}

Obs! Om du vill publicera din app i F-Droid-appbutiken måste du använda magiska nummer i gradfilen, för annars kan inte f-droid-roboten läsa aktuell version för att upptäcka / verifiera versionändringar.

Visa signeringsinformation

Under vissa omständigheter (till exempel att skaffa en Google API-nyckel) måste du hitta ditt fingeravtryck i din nyckelhandel. Gradle har en bekväm uppgift som visar all signeringsinformation, inklusive fingeravtryck för tangentlagring:

./gradlew signingReport

Detta är ett provutgång:

:app:signingReport
Variant: release
Config: none
----------
Variant: debug
Config: debug
Store: /Users/user/.android/debug.keystore
Alias: AndroidDebugKey
MD5: 25:08:76:A9:7C:0C:19:35:99:02:7B:00:AA:1E:49:CA
SHA1: 26:BE:89:58:00:8C:5A:7D:A3:A9:D3:60:4A:30:53:7A:3D:4E:05:55
Valid until: Saturday 18 June 2044
----------
Variant: debugAndroidTest
Config: debug
Store: /Users/user/.android/debug.keystore
Alias: AndroidDebugKey
MD5: 25:08:76:A9:7C:0C:19:35:99:02:7B:00:AA:1E:49:CA
SHA1: 26:BE:89:58:00:8C:5A:7D:A3:A9:D3:60:4A:30:53:7A:3D:4E:05:55
Valid until: Saturday 18 June 2044
----------
Variant: debugUnitTest
Config: debug
Store: /Users/user/.android/debug.keystore
Alias: AndroidDebugKey
MD5: 25:08:76:A9:7C:0C:19:35:99:02:7B:00:AA:1E:49:CA
SHA1: 26:BE:89:58:00:8C:5A:7D:A3:A9:D3:60:4A:30:53:7A:3D:4E:05:55
Valid until: Saturday 18 June 2044
----------
Variant: releaseUnitTest
Config: none
----------

Definiera byggtyper

Du kan skapa och konfigurera bygga typer i modulen nivå build.gradle fil inne i android {} block.

    android {
        ...
        defaultConfig {...}
    
        buildTypes {
            release {
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
    
            debug {
                applicationIdSuffix ".debug"
            }
        }
    }


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow