Android
Gradle för Android
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 internaversionCode
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
- Den officiella gradle-hemsidan
- Hur man konfigurerar gradle builds
- Android-plugin för gradle
- Android Gradle DSL
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:
- lagring i en extern fil
- lagra dem i inställning av miljövariabler .
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 ikeystore.properties
filen ska vara relativt dinbuild.gradle
fil. Detta exempel antar att keystore-filen finns i samma katalog som appensbuild.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 irootProject.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
- en separat gradering inkluderar fil Centraliserande beroenden via filen "dependensions.gradle"
- en fristående egenskapsfil Versionering av dina builds via "version.properties" -filen
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" } } }