Поиск…


Вступление

Gradle - это система сборки на основе JVM, которая позволяет разработчикам писать высокоуровневые сценарии, которые могут использоваться для автоматизации процесса компиляции и создания приложений. Это гибкая система на основе плагинов, которая позволяет автоматизировать различные аспекты процесса сборки; включая компиляцию и .jar , загрузку и управление внешними зависимостями, ввод полей в AndroidManifest или использование определенных версий SDK.

Синтаксис

  • apply plugin : плагины, которые обычно должны использоваться только 'com.android.application' или 'com.android.library' .

  • android : основная конфигурация вашего приложения

    • compileSdkVersion : скомпилированная версия SDK
    • buildToolsVersion : версия инструмента сборки
    • defaultConfig : настройки по умолчанию, которые могут быть перезаписаны вкусами и типами сборки
      • applicationId : идентификатор приложения, который вы используете, например, в PlayStore, в основном совпадает с именем вашего пакета
      • minSdkVersion : минимальная требуемая версия SDK
      • targetSdkVersion : SDK-версия, с которой вы компилируете (всегда должна быть новая)
      • versionCode : внутренний номер версии, который должен быть больше при каждом обновлении
      • versionName : номер версии, которую пользователь может видеть на странице сведений о приложении
    • buildTypes : см. где-то еще (TODO)
  • dependencies : maven или локальные зависимости вашего приложения

    • compile одну зависимость
    • testCompile : зависимость для модульных или интеграционных тестов

замечания

Смотрите также

Gradle for Android - Расширенная документация:

Существует еще один тег, где вы можете найти больше тем и примеров использования градиента в Android.
http://www.riptutorial.com/topic/2092

Базовый файл build.gradle

Это пример файла build.gradle умолчанию в модуле.

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 (язык, специфичный для домена)

Каждый блок в указанном выше файле называется DSL (специфичным для домена языком).


Плагины

В первой строке apply plugin: 'com.android.application' , применяет плагин Android для Gradle к сборке и блокирует блок android {} для объявления вариантов сборки для Android.

Для Android-приложения :

apply plugin: 'com.android.application'

Для Android-библиотеки :

apply plugin: 'com.android.library'

Понимание DSL в приведенном выше образце

Вторая часть, блок android {...} - это Android DSL который содержит информацию о вашем проекте.

Например, вы можете установить compileSdkVersion который определяет уровень API Android, который должен использоваться Gradle для компиляции вашего приложения.
В defaultConfig содержатся значения по умолчанию для вашего манифеста. Вы можете override их с помощью продуктов Flavors .

Вы можете найти больше информации в этих примерах:


зависимости

Блок dependencies определяется вне блока android {...} : это означает, что он не определен плагином Android, но это стандартный Gradle.
Блок dependencies определяет, какие внешние библиотеки (как правило, библиотеки Android, но библиотеки Java также действительны), которые вы хотите включить в свое приложение. Gradle автоматически загрузит эти зависимости для вас (если локальная копия отсутствует), вам просто нужно добавить похожие строки compile если вы хотите добавить другую библиотеку.

Давайте посмотрим на одну из представленных здесь строк:

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

Эта строка в основном говорит

добавьте зависимость от библиотеки дизайна поддержки Android к моему проекту.

Gradle гарантирует, что библиотека будет загружена и представлена, чтобы вы могли использовать ее в своем приложении, а ее код также будет включен в ваше приложение.

Если вы знакомы с Maven, этот синтаксис - это GroupId , двоеточие, ArtifactId , другой двоеточие, а затем версия зависимости, которую вы хотите включить, что дает вам полный контроль над версиями.

Хотя можно указать версии артефакта, используя знак плюса (+), лучше всего избегать этого; это может привести к проблемам, если библиотека будет обновлена ​​с нарушением изменений без вашего ведома, что, вероятно, приведет к сбоям в вашем приложении.

Вы можете добавить различные зависимости:

Особое внимание должно быть уделено плоской зависимости aar .

Вы можете найти более подробную информацию в этой теме.

Обратите внимание на -v7 в appcompat-v7

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

Это просто означает, что эта библиотека ( appcompat ) совместима с уровнем API Android 7 и appcompat .

Примечание о junit: junit: 4.12

Это тестовая зависимость для модульного тестирования.


Указание зависимостей, характерных для разных конфигураций компоновки

Вы можете указать, что зависимость должна использоваться только для определенной конфигурации сборки или вы можете определить различные зависимости для типов сборки или продуктов (например, отладка, тестирование или выпуск) с помощью debugCompile , testCompile или releaseCompile вместо обычного compile ,

Это полезно для хранения зависимостей, связанных с тестированием и отладкой, из вашей сборки релиза, что позволит вашей версии APK как можно более тонкой и поможет гарантировать, что любая информация об отладке не может использоваться для получения внутренней информации о вашем приложении.


signingConfig

signingConfig позволяет вам настроить Gradle для включения информации о keystore и убедиться, что APK, построенный с использованием этих конфигураций, подписан и готов к выпуску Play Store.

Здесь вы можете найти специальную тему .

Примечание . Не рекомендуется сохранять учетные данные подписи в вашем файле Gradle. Чтобы удалить настройки подписи, просто опустите часть signingConfigs .
Вы можете указать их по-разному:

См. Эту тему для получения более подробной информации: Подпишите APK без раскрытия пароля хранилища ключей .


Вы можете найти дополнительную информацию о Gradle для Android в теме Gradle .

Определение вкусов продукта

build.gradle продукта определены в файле build.gradle внутри блока android { ... } как показано ниже.

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

Делая это, у нас теперь есть два дополнительных продукта: free и paid . Каждый из них может иметь свою собственную конфигурацию и атрибуты. Например, оба наших новых вкуса имеют отдельное имя applicationId и versionName чем наш существующий main аромат (доступный по умолчанию, поэтому не показан здесь).

Добавление зависимых от продукта вкусовых зависимостей

Зависимости могут быть добавлены для конкретного вкуса продукта , аналогично тому, как они могут быть добавлены для конкретных конфигураций сборки.

В этом примере предположим, что мы уже определили два продукта, называемых free и paid (подробнее об определении вкусов здесь ).
Затем мы можем добавить зависимость AdMob для free аромата и библиотеку Picasso для paid например:

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'
} 
...

Добавление ресурсов, специфичных для продукта

Ресурсы могут быть добавлены для конкретного продукта .

В этом примере предположим, что мы уже определили два продукта, называемых free и paid . Чтобы добавить ресурсы, специфичные для продукта, мы создаем дополнительные папки ресурсов вместе с папкой main/res , которые затем можно добавить к ресурсам, как обычно. В этом примере мы определим строку, status , для каждого продукта:

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

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

/ src / free /res/values/strings.xml

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

/ src / paid /res/values/strings.xml

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

Строки status специфичные для вкуса продукта, переопределяют значение status в main ароматизаторе.

Определение и использование полей конфигурации сборки

BuildConfigField

Gradle позволяет buildConfigField определять константы. Эти константы будут доступны во время выполнения в качестве статических полей класса BuildConfig . Это можно использовать для создания ароматов , определяя все поля в блоке defaultConfig , а затем переопределяя их для отдельных defaultConfig сборки по мере необходимости.

В этом примере определяется дата сборки и флаги сборки для производства, а не теста:

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'
        }
    }
}

Автоматически созданное <имя_пакета>. BuildConfig .java в папке gen содержит следующие поля на основе указанной выше директивы:

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";
}

Определенные поля теперь можно использовать в приложении во время выполнения, BuildConfig к сгенерированному классу BuildConfig :

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 в productFlavors создает значение ресурса. Это может быть любой тип ресурсов ( string , dimen , color и т. Д.). Это похоже на определение ресурса в соответствующем файле: например, определение строки в файле strings.xml . Преимущество состоит в том, что тот, который определен в градиенте, может быть изменен на основе вашего productFlavor / buildVariant. Чтобы получить доступ к значению, напишите тот же код, как если бы вы получали доступ к res из файла ресурсов:

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

Важно то, что ресурсы, определенные таким образом, не могут изменять существующие ресурсы, определенные в файлах. Они могут создавать только новые значения ресурсов.


Некоторым библиотекам (например, API Android для Google Maps) требуется ключ API, указанный в манифесте в качестве тега meta-data . Если для отладочной и производственной сборки нужны разные ключи, укажите манифест заполнителя, заполненный Gradle.

В вашем файле AndroidManifest.xml :

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

Затем установите соответствующее поле в файле build.gradle :

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

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

Система сборки Android автоматически генерирует несколько полей и помещает их в BuildConfig.java . Эти поля:

поле Описание
DEBUG Boolean сообщение, если приложение находится в режиме отладки или выпуска
APPLICATION_ID String содержащая идентификатор приложения (например, com.example.app )
BUILD_TYPE String содержащая тип сборки приложения (обычно либо debug либо release )
FLAVOR String содержащая особый аромат сборки
VERSION_CODE int содержащий номер версии (сборки).
Это то же самое , как versionCode в build.gradle или versionCode в AndroidManifest.xml
VERSION_NAME String содержащая имя версии (сборки).
Это то же самое , как versionName в build.gradle или versionName в AndroidManifest.xml

В дополнение к вышесказанному, если вы определили несколько параметров вкуса, то каждое измерение будет иметь свое значение. Например, если у вас есть два размера аромата для color и size вас также будут следующие переменные:

поле Описание
FLAVOR_color String содержащая значение для цветового оттенка.
FLAVOR_size String содержащая значение для аромата размера.

Централизация зависимостей через файл «dependencies.gradle»

При работе с многомодульными проектами полезно централизовать зависимости в одном месте, а не распространять их во многих файлах сборки, особенно для обычных библиотек, таких как библиотеки поддержки Android и библиотеки Firebase .

Одним из рекомендуемых способов является разделение файлов сборки Gradle с одним build.gradle на модуль, а также с одним в корне проекта и другим для зависимостей, например:

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

Затем все ваши зависимости могут быть расположены в 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}",
    ];
}

Который может быть применен из этого файла в файле верхнего уровня build.gradle следующим образом:

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

и в module1/build.gradle :

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

Другой подход

Менее подробный подход для централизации версий зависимостей библиотек может быть достигнут путем объявления номера версии как переменной один раз и использования ее повсюду.

В рабочей области root build.gradle добавьте следующее:

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

И в каждом модуле, который использует одну и ту же библиотеку, добавьте необходимые библиотеки

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}"

Структура каталогов для ресурсов, специфичных для вкуса

Различные варианты создания приложений могут содержать разные ресурсы. Чтобы создать ресурс, специфичный для вкуса, создайте каталог с наименьшим именем вашего аромата в каталоге src и добавьте свои ресурсы таким же образом, как вы обычно.

Например, если у вас есть аромат Development и вы хотите предоставить отдельный значок запуска, вы должны создать каталог src/development/res/drawable-mdpi а внутри этого каталога создайте файл ic_launcher.png с вашим значком, зависящим от конкретной разработки.

Структура каталогов будет выглядеть так:

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'

(Конечно, в этом случае вы также создадите значки для drawable-hdpi, drawable-xhdpi и т . Д. ).

Почему в проекте Android Studio есть два файла build.gradle?

<PROJECT_ROOT>\app\build.gradle специфичен для модуля приложения .

<PROJECT_ROOT>\build.gradle - это «файл сборки верхнего уровня», где вы можете добавить параметры конфигурации, общие для всех подпроектов / модулей.

Если вы используете другой модуль в своем проекте, в качестве локальной библиотеки у вас будет другой файл build.gradle : <PROJECT_ROOT>\module\build.gradle

В файле верхнего уровня вы можете указать общие свойства как блок buildscript или некоторые общие свойства.

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"
}

В app\build.gradle вы определяете только свойства для модуля:

apply plugin: 'com.android.application'


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

dependencies {
    //.....
}

Выполнение скрипта оболочки из градиента

Сценарий оболочки - это очень универсальный способ расширить вашу сборку до практически всего, что вы можете придумать.

В качестве примера, вот простой скрипт для компиляции файлов protobuf и добавления результирующих java-файлов в исходный каталог для дальнейшей компиляции:

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

project.afterEvaluate {
    compilePb()
}

Сценарий оболочки «pbScript.sh» для этого примера, расположенный в корневой папке проекта:

#!/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

Отладка ошибок Gradle

Ниже приведена отрывок из Gradle. Что такое ненулевое значение выхода и как его исправить? , см. его для полного обсуждения.

Предположим, вы разрабатываете приложение, и вы получаете некоторую ошибку Gradle, которая появляется, как правило, будет выглядеть так.

: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

Вы ищете здесь, в StackOverflow, для своей проблемы, и люди говорят, чтобы очистить и перестроить ваш проект, или включить MultiDex , и когда вы попробуете это, это просто не устраняет проблему.

Есть способы получить дополнительную информацию , но сам вывод Gradle должен указывать на фактическую ошибку в нескольких строках над этим сообщением между: module:someTask FAILED и последним :module:someOtherTask который прошел. Поэтому, если вы зададите вопрос о своей ошибке, отредактируйте свои вопросы, чтобы включить больше контекста в ошибку.

Таким образом, вы получаете «ненулевое значение выхода». Ну, это число является хорошим показателем того, что вы должны попытаться исправить. Вот несколько наиболее часто встречающихся случаев.

  • 1 является просто общим кодом ошибки, и ошибка, скорее всего, в выходе Gradle
  • 2 похоже, связано с перекрывающимися зависимостями или неправильной конфигурацией проекта.
  • 3 похоже, связано со слишком большим количеством зависимостей или проблемой памяти.

Общие решения для вышеизложенного (после попытки «Очистить и перестроить проект»):

  • 1 - Обратите внимание на указанную ошибку. Как правило, это ошибка времени компиляции, то есть некоторая часть кода в вашем проекте недопустима. Это включает в себя как XML, так и Java для Android-проекта.
  • 2 и 3 - Многие ответы здесь дают вам возможность включить multidex . Хотя это может решить проблему, это, скорее всего, обходной путь. Если вы не понимаете, почему вы его используете (см. Ссылку), вам, вероятно, это не понадобится. Общие решения включают в себя сокращение чрезмерного использования зависимостей библиотек (например, от всех сервисов Google Play, когда вам нужно использовать только одну библиотеку, например, Карты или Вход в систему).

Указание различных идентификаторов приложений для типов и типов продуктов

Вы можете указать разные идентификаторы приложений или имена пакетов для каждого типа buildType или productFlavor используя атрибут конфигурации applicationIdSuffix :

Пример суффикса applicationId для каждого типа 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"
    }
}

В результате мы applicationIds :

  • com.package.android для release
  • com.package.android. dev для development
  • com.package.android. qa для testing

Это можно сделать и для productFlavors :

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

Результирующее applicationIds будет:

  • com.package.android. бесплатно для free вкуса
  • com.package.android. заплатил за paid аромат

Подписать APK без раскрытия пароля хранилища ключей

Вы можете определить конфигурацию подписи, чтобы подписать apk в файле build.gradle используя следующие свойства:

  • storeFile : файл хранилища ключей
  • storePassword : пароль хранилища ключей
  • keyAlias : ключевое имя псевдонима
  • keyPassword : пароль псевдонима ключа

Во многих случаях вам может потребоваться избежать такой информации в файле build.gradle .

Способ A: Настроить подпись выпуска с помощью файла keystore.properties.

Можно сконфигурировать build.gradle вашего приложения, чтобы он считывал вашу информацию о настройке build.gradle из файла свойств, такого как keystore.properties .

Настройка подписи так же выгодна, потому что:

  • Ваша информация о настройке build.gradle отделена от файла build.gradle
  • Вам не нужно вмешиваться во время процесса подписания, чтобы предоставить пароли для файла хранилища ключей
  • Вы можете легко исключить файл keystore.properties из управления версиями

Во-первых, создайте файл с именем keystore.properties в корневом каталоге вашего проекта с таким содержимым (заменив значения собственными):

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

Теперь в файле build.gradle вашего приложения signingConfigs блок signingConfigs следующим образом:

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']
            }
        }
    }
}

Это действительно все, что нужно, но не забудьте исключить как ваш файл keystore.properties файл keystore.properties из управления версиями .

Несколько вещей, чтобы отметить:

  • storeFile путь , указанный в keystore.properties файл должен быть относительно вашего приложения build.gradle файла. В этом примере предполагается, что файл хранилища ключей находится в том же каталоге, что и файл build.gradle приложения.
  • В этом примере файл keystore.properties в корне проекта. Если вы поместите его в другое место, обязательно измените значение в rootProject.file('keystore.properties') на ваше местоположение по отношению к корню вашего проекта.

Метод B: используя переменную окружения

То же самое можно сделать и без файла свойств, что затрудняет поиск пароля:

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" может быть глобальной, но более безопасный подход может заключаться в добавлении ее в оболочку Android Studio.
В linux это можно сделать, отредактировав Desktop Entry Studio Desktop Entry

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

Вы можете найти более подробную информацию в этой теме .

Версии ваших сборников через файл «version.properties»

Вы можете использовать Gradle для автоматического увеличения вашей версии пакета каждый раз, когда вы его создаете. Для этого создайте файл version.properties в том же каталоге, что и ваш build.gradle со следующим содержимым:

VERSION_MAJOR=0
VERSION_MINOR=1
VERSION_BUILD=1

(Изменение значений для основного и второстепенного, как вы сочтете нужным). Затем в build.gradle добавьте следующий код в раздел android :

// 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)
  }
}

Информацию можно получить в Java в виде строки BuildConfig.VERSION_NAME для полного {major}. { BuildConfig.VERSION_NAME }. {Build} числа и как целое BuildConfig.VERSION_CODE только для номера сборки.

Изменение имени файла apk и добавление имени версии:

Это код для изменения имени файла прикладного приложения (.apk). Имя можно настроить, присвоив другому значению 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 + "]");
        }
    }
}

Отключить сжатие изображения для меньшего размера файла APK

Если вы оптимизируете все изображения вручную, отключите APT Cruncher для меньшего размера файла APK.

android {
    
    aaptOptions {
        cruncherEnabled = false
    }
}

Включить Proguard с помощью gradle

Для включения конфигураций Proguard для вашего приложения вам необходимо включить его в файл уровня градиента на уровне модуля. Вы должны установить значение minifyEnabled true .

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

Вышеприведенный код применит ваши конфигурации Proguard, содержащиеся в стандартном Android SDK в сочетании с файлом «proguard-rules.pro» на вашем модуле, в ваш выпущенный apk.

Включить поддержку экспериментального NDK-плагина для Gradle и AndroidStudio

Включите и настройте экспериментальный плагин Gradle для улучшения поддержки NDK AndroidStudio. Убедитесь, что вы выполняете следующие требования:

  • Gradle 2.10 (для этого примера)
  • Android NDK r10 или новее
  • Android SDK с инструментами построения v19.0.0 или новее

Настроить файл MyApp / build.gradle

Отредактируйте строку dependencies.classpath в файле build.gradle, например

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

в

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

(v0.7.2 была последней версией на момент написания. Проверьте последнюю версию самостоятельно и соответствующим образом адаптируйте свою линию)

Файл build.gradle должен выглядеть примерно так:

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

allprojects {
    repositories {
        jcenter()
    }
}

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

Настроить файл MyApp / app / build.gradle

Отредактируйте файл build.gradle, чтобы он выглядел примерно так, как показано в следующем примере. Номера версий могут отличаться.

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'])
}

Синхронизируйте и проверьте, нет ли ошибок в файлах Gradle перед продолжением.

Проверить, включен ли плагин

Сначала убедитесь, что вы загрузили модуль Android NDK. Затем создайте новое приложение в AndroidStudio и добавьте следующее в файл ActivityMain:

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

Часть getString() должна быть выделена красным цветом, говоря, что соответствующая функция JNI не найдена. Наведите указатель мыши на вызов функции, пока не появится красная лампочка. Щелкните лампу и выберите create function JNI_... Это должно сгенерировать файл myLib.c в каталоге myApp / app / src / main / jni с правильным вызовом функции JNI. Он должен выглядеть примерно так:

#include <jni.h>

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

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

Если это не так, то плагин не был настроен правильно или NDK не был загружен

Показать все задачи проекта gradle

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

Немедленно удалить «неприглаженный» apk

Если вам не нужны автоматически сгенерированные файлы apk с unaligned суффиксом (которого вы, вероятно, нет), вы можете добавить следующий код для файла build.gradle :

// 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()
        }
    }
  }
}

Отсюда

Игнорирование варианта сборки

По некоторым причинам вы можете игнорировать свои варианты сборки. Например: у вас есть «макет» вкуса продукта, и вы используете его только для целей отладки, таких как тестирование единиц / контрольно-измерительных приборов.

Давайте проигнорируем вариант mockRelease из нашего проекта. Откройте файл build.gradle и напишите:

    // 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);
        }
    }

Просмотр дерева зависимостей

Используйте зависимости задачи. В зависимости от того, как настроены ваши модули, это могут быть ./gradlew dependencies или посмотреть зависимости использования приложения модуля ./gradlew :app:dependencies

Пример, следующий за файлом build.gradle

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'
}

будет отображать следующий график:

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 (*)

. . .

Здесь вы можете увидеть, что проект напрямую включает в себя com.android.support:design версию 23.2.1, которая сама приносит com.android.support:support-v4 с версией 23.2.1. Однако com.google.android.gms:play-services самих com.google.android.gms:play-services есть зависимость от той же support-v4 но с более старой версией 21.0.0, которая является конфликтом, обнаруженным методом gradle.

(*) используются, когда gradle пропускает поддерево, потому что эти зависимости уже были указаны ранее.

Используйте gradle.properties для центральной версии номера / buildconfigurations

Вы можете определить центральную конфигурационную информацию в

или сделать это с корневым файлом gradle.properties

структура проекта

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

глобальная настройка для всех подмодулей в 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

использование в подмодуле

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 {
    ...
}

Примечание. Если вы хотите опубликовать свое приложение в магазине приложений F-Droid, вы должны использовать магические числа в файле gradle, потому что еще один робот f-droid не может читать текущую версию nnnner для обнаружения / проверки изменений версии.

Отображение информации о подписке

В некоторых случаях (например, при получении ключа API Google) вам нужно найти отпечаток своего хранилища ключей. У Gradle есть удобная задача, отображающая всю информацию о подписке, включая отпечатки ключей:

./gradlew signingReport

Это примерный результат:

: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
----------

Определение типов сборки

Вы можете создавать и настраивать типы сборки в файле build.gradle уровне build.gradle внутри блока android {} .

    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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow