Android studio gradle examples

Gradle

Gradle — система автоматической сборки, построенная на принципах Apache Ant и Apache Maven. В Eclipse использовалась система Ant, но большинство разработчиков даже не замечало её работы. В основном возможности системы использовались в конторах для автоматизации различных задач. В Android Studio такой номер не пройдёт. Gradle сопровождает вас во время разработки постоянно. Поначалу, если вы перешли с Eclipse, Gradle сильно раздражает своими действиями. Но позже вы оцените её удобство и может даже полюбите её.

Gradle не является изобретением для Android Studio, система была разработана раньше и использовалась в приложениях для Java, Scala и других языках.

Система сборки Gradle очень мощная и сложная, чтобы о ней рассказать в двух словах. Есть целые книги о ней. Сами команды в Gradle представляют собой обычный текст с использованием синтаксиса Groove для конфигурации. Но нам не нужно знать всё. Познакомимся поближе с системой и научимся пользоваться ей.

Создайте новый проект или откройте любой существующий проект из Android Studio и посмотрите на структуру проекта.

В последних версиях студии файлы Gradle выделили в отдельную папку Gradle Script. Раскройте её. В основном вас должен интересовать файл build.gradle, который относится к модулю. Рядом с этим файлом в скобках будет написано Module: app. Двойным щелчком откройте его, вы увидите, что файл является текстовым.

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

Вернёмся к файлу модуля, вы увидите много интересной информации. Например, вы там можете увидеть настройки, которые раньше вы могли видеть в манифесте — номера версий, номера SDK и так далее. Забегая вперёд, скажу, что здесь можно добавить всего одну волшебную строчку и нужная библиотека сама скачается из интернета и установится в проекте. Красота!

Однако вернёмся в корневую папку. Кроме файлов build.gradle мы можем заметить файлы gradle.properties, settings.gradle и другие. Трогать их не нужно.

В корневой папке также есть файлы gradlew и gradlew.bat для работы с Gradle Wrapper. В принципе вам не нужно знать о них ничего. Но для параноиков есть информация — если вы часто импортируете проекты из неизвестных источников, то они содержат файл gradle/wrapper/gradle-wrapper.properties. Откройте его текстовым редактором и посмотрите на адрес у distributionUrl. Путь должен вести на официальный сай //services.gradle.org или на внутренний корпоративный сервер. Другие адреса должны вызвать тревогу.

Вы могли заметить, что по сравнению с Eclipse изменилась структура файлов. В папке app находится папка src, а ней папка main, в которых папки java, res и файл манифеста. Новая структура лучше отвечает требованиям Gradle для управления файлами.

Вы, например, можете создавать альтернативные папки с ресурсами и с помощью build.gradle подключить их к проекту.

В этом примере мы указали, что существуют новая папка presentations в папке /src/main/ наряду с существующими папками java и res. Внутри созданной папки есть ещё две папки layout и animations, которые содержат файлы ресурсов.

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

Значение sourceSets указывает Gradle, какие папки следует использовать. Этим приёмом пользуются продвинутые программисты. Мы пока не будем использовать такую технику.

Другая полезная возможность — создавать разные версии приложений, например, демо-версию и платную версию. Немного об этом рассказано здесь.

Номер версии приложения и требования к версии Android прописаны в секции defaultConfig. Если у вас сохранились старые версии приложений, то в манифесте можете удалить данные записи. По-моему, там даже выводится соответствующая подсказка. Даже если вы эти данные в манифесте не удалите, то значения из gradle.build имеют больший приоритет и перепишут значения в манифесте при не совпадении.

Подключение библиотеки происходит одной строчкой. Например, нужно добавить библиотеку Picasso:

В Android Studio 3.0 используется новая версия Gradle, в которой compile считается устаревшей. Вместо него следует использовать новое слово implementation.

Есть похожая команда, которая подключает библиотеку, которая будет использоваться только для отладки приложения и в релизной версии она не нужна.

Далее включаете синхронизацию и через несколько секунд в папке появляется нужная библиотека, готовая к использованию. Сама библиотека скачивается с специального хранилища-репозитория JCenter. Данный репозиторий используется по умолчанию и прописан в buil.gradle проекта.

Можно указать другой репозиторий, например, Maven Central.

Для поиска через Maven-репозиторий используйте The Central Repository Search Engine.

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

Сам файл нужно скопировать в папку /libs.

При любом изменении файла недостаточно его сохранить. Нужно также произвести синхронизацию. Наверху обычно появляется жёлтая полоска с ссылкой Sync Now.

Задаём имя APK при компиляции

Можно задать собственное имя при компиляции проекта. Например, так.

Получим имя MyName-1.0.12-release.apk

Оптимизатор кода R8

Оптимизатор кода R8 имеет следующие возможности: урезание байт-кода, сжатие, обфускация, оптимизация, удаление «синтаксического сахара», преобразование в DEX. Оптимизатор может производить все операции за один шаг, что даёт сильное улучшение производительности. R8 был введён в Android Gradle plugin 3.3.0. Вам нужно только включить его.

Читайте также:  Save data unity android

R8 разработан для работы с существующими ProGuard-правилами, хотя возможны ситуации, когда нужно переработать правила.

Сжимаем итоговый APK

В Gradle 1.4 появилась возможность сжать итоговый файл, убрав неиспользуемые ресурсы, в том числе из библиотек, например, Google Play Services.

Во время сборки приложения вы можете увидеть строку:

Другой способ убрать неиспользуемые ресурсы конфигурации. Например, вам не нужные локализованные ресурсы для всех языков, которые входят в библиотеку Google Play Services или Android Support Library и др. Оставим только нужные языки. Возможно, вы также не хотите поддерживать mdpi или tvdpi-разрешения в своём приложении. Мы можем установить языки и разрешения, которые используются в приложении, остальные будут исключены, что позволит уменьшить вес приложения.

Можно перенести ключи из манифеста.

Чтобы их не светить, например, если выкладывать код на Гитхабе, то сделаем так.

И в манифесте переделаем код.

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

В манифесте пишем.

Класс BuildConfig

В статье LogCat упоминался способ быстрого отключения журналирования.

Суть в следующем. Когда вы создаёте новые переменные в блоках defaultConfig или buildTypes (ветки debug и release), то Gradle создаёт специальный класс BuildConfig, и вы можете получить доступ к этим переменным.

Например, добавим переменную в defaultConfig

На языке Java это равносильно String YOUR_TOKEN = «ABRAKADABRA»;

Теперь мы можем обратиться к созданной строке.

С секцией buildType ситуация интереснее. У секции есть два блока debug и release. Можно создать переменные с разными значениями, которые будут использоваться в зависимости от ситуации. Например, у вас есть собственное API для сервера. Для тестирования вы используете один адрес, а для финальной версии — другой адрес. Тогда вы просто указываете разные адреса в разных ветках. Переменные могут быть не только строковыми.

Создаём код для перехода на веб-страницу.

Теперь вам не нужно переписывать каждый раз код. Загружаться будет страница по нужному адресу автоматически.

Разделяем отладочную и финальную версию

По такому же принципу можно организовать запуск новой версии программы, не затрагивая программу, которую вы установили с Google Play. Допустим вы на своём телефоне установили своё собственное приложение через Google Play. Теперь вам нужно написать новую версию и проверить на своём телефоне. Из-за конфликта имён новое тестируемое приложение перепишет финальную версию или вообще не установится. Поможет следующий трюк.

В специальных переменных applicationIdSuffix и versionNameSuffix мы задаём суффиксы, чтобы избежать конфликта. А в переменной resValue указываем название программы для отладочной и финальных версий, чтобы на устройстве можно было их найти. Не забудьте при этом удалить строковый ресурс app_name в res/values/strings.xml, иначе получите ошибку при компиляции. Теперь можете спокойно запускать приложение с новым кодом, не боясь повредить своё любимое приложение.

Прячем секретную информацию

Следующий совет больше подходит для компаний. Когда подписывается приложение, то нужно указывать пароль, хранилище и т.д. Чтобы их не светить в студии, можно прописать их в переменных и поместить в секцию signingConfigs. Сервер сам найдёт нужные ключи и воспользуется ими в своих сценариях.

Автогенерация версии кода

Нашёл совет, сам не применял. Не обязательно вручную менять версию приложения в атрибутах versionCode и versionName, можно сделать через переменные, а они сами подставятся в нужное место. На любителя.

settings.gradle

Файл settings.gradle обычно состоит из одной строчки.

Это означает, что у вас используется один проект для работы. Если вы будете подключать другие проекты, то здесь появятся новые строки.

gradle.properties (Project Properties)

Несколько советов по настройке файла gradle.properties.

Режим параллельного выполнения

В этом файле можно найти закомментированную строку # org.gradle.parallel=true. Если модули вашего проекта не используют друг друга как зависимости, создавая перекрёстные ссылки, можно включать режим параллельного выполнения, что ускорит скорость сборки до

Gradle-демон

Включение на компьютере демона Gradle даст значительный прирост в скорости сборки.

Режим конфигурации при необходимости

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

Меняем номер версии библиотек в одном месте

Очень часто в проекте используются взаимосвязанные библиотеки с одинаковыми номерами.

Можно быстро поменять у всех номера через переменную. Для этого используется секция ext, в которой указывается переменная и номер версии. Затем в секции dependencies номер версии заменяется на имя переменной

Обратите внимание, что одинарные кавычки заменяются на двойные, а символ $ указывает на строковый тип.

Расширенная версия с разными переменными в другом виде.

Если в проекте используются несколько модулей с одинаковыми зависимостями, то эти записи можно перенести в корневой build.gradle, чтобы не менять номера версий в каждом модуле.

Настройки в Android Studio

Рассмотрим настройки, доступные в Android Studio. Закройте текущий проект, чтобы увидеть стартовое окно студии. В правой части нажмите на пункт Configure. В следующем окне выберите пункт Settings, чтобы оказаться в окне настроек студии. В левой части найдите пункт Build, Execution, Deployment, затем подпункт Build Tools, далее подпункт Gradle. По умолчанию, там всё чисто, только указан путь у Service directory path. Это были общие настройки.

Теперь рассмотрим настройки, относящиеся к проекту. Запустите любой проект в Android Studio. Выберите меню File | Settings. . Снова пройдитесь по пунктам Build, Execution, Deployment | Build Tools | Gradle. Вы увидите практически такое же окно с небольшими изменениями. Теперь поле Linked Gradle Projects не будет пустым, а также появятся дополнительные настройки. По умолчанию рекомендуют использовать Use default gradle wrapper.

Читайте также:  Scrolling pages in android

Gradle Task

На правой стороне Android Studio имеется вертикальная вкладка Gradle, которую можно развернуть. Она содержит список задач (task), которая выполняет Gradle при работе с текущим проектом. Вы можете выделить любую из этих задач и запустить её двойным щелчком. Можно выделить несколько задач.

Узнать debug.keystore: MD5 и SHA1

Иногда требуется узнать значения debug.keystore: MD5 и SHA1. Обычно их получают через командную строку. Но это долго и неудобно, так как нужно помнить все аргументы. Есть способ проще. Открываем вкладку Gradle, нажимаем на кнопку со стрелками Refresh all Gradle Projects. Затем последовательно открываем элементы Tasks | android и запускаем команду signingReport. В нижнем окне Run увидите нужную информацию.

Gradle Console

Когда выполняется какая-то задача Gradle, то ход её выполнения можно увидеть в окне Gradle Console. Открыть её можно через вкладку Gradle Console в нижней правой части студии.

Terminal

Запускать задачи Gradle можно и в окне Terminal.

На панели инструментов имеется значок Sync Project with Gradle Files, которую следует использовать при редактировании файлов Gradle. Как правило, студия также выводит предупреждающее сообщение с ссылкой при изменении файла, которая делает ту же работу.

Добавление зависимостей через интерфейс студии

В статье описывался способ включения библиотеки в проект через редактирование файла build.gradle. Существует альтернативный вариант через настройки студии. Щёлкните правой кнопкой мыши на имени модуля (app) и выберите пункт Open Module Settings (быстрая клавиша F4). В правой части окна находятся вкладки, которые оказывают влияние на файл build.gradle. Например, вкладка Dependencies содержит подключаемые библиотеки.

Чтобы добавить новую зависимость, нажмите на значок с плюсом и выберите нужный вариант, например, Library dependency. Откроется список доступных библиотек из репозитория Maven.

Дополнительное чтение

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

Задачи Gradle — теория для общего развития.

Источник

Шпаргалка по Gradle

Как мне кажется, большинство людей начинают разбираться с gradle только тогда, когда в проекте что-то надо добавить или что-то внезапно ломается — и после решения проблемы «нажитый непосильным трудом» опыт благополучно забывается. Причём многие примеры в интернете похожи на ускоспециализированные заклинания, не добавляющие понимания происходящего:

Я не собираюсь подробно описывать, для чего нужна каждая строчка выше — это частные детали реализации андроид-плагина. Есть кое-что более ценное — понимание того, как всё организовано. Информация раскидана по различным сайтам/официальной документации/исходникам градла и плагинов к нему — в общем, это чуть более универсальное знание, которое не хочется забывать.

Дальнейший текст можно рассматривать как шпаргалку для тех, кто только осваивает gradle или уже забыл.

Полезные ссылки

Консоль

Android studio/IDEA старательно прячет команды gradle от разработчика, а ещё при изменении build.gradle файликов начинает тупить или перезагружать проект.

В таких случаях вызывать gradle из консоли оказывается намного проще и быстрее. Враппер для gradle обычно идёт вместе с проектом и прекрасно работает в linux/macos/windows, разве что в последнем надо вызывать bat-файлик вместо враппера.

Вызов задач

пишет доступные задачи.

Можно вывести задачи отдельного подпроекта, а ещё с опцией —all будут выведены все задачи, включая второстепенные.

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

Если лень писать название целиком, можно выкинуть маленькие буковки:

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

Логгинг

Количество выводимой в консоль информации при запуске задачи сильно зависит от уровня логгинга.
Кроме дефолтного есть -q, -w, -i, -d , ну или —quiet, —warn, —info, —debug по возрастанию количества информации. На сложных проектах вывод с -d может занимать больше мегабайта, а поэтому его лучше сразу сохранять в файл и там уже смотреть поиском по ключевым словам:

Если где-то кидается исключение, для stacktrace опция -s .

Можно и самому писать в лог:

логгер является имплементацией SLF4J.

Groovy

Происходящее в build.gradle файликах — просто код на groovy.

Groovy как язык программирования почему-то не очень популярен, хотя, как мне кажется, он сам по себе достоин хотя бы небольшого изучения. Язык появился на свет ещё в 2003 году и потихоньку развивался. Интересные особенности:

  • Практически любой java код является валидным кодом на groovy. Это очень помогает интуитивно писать работающий код.
  • Одновременно вместе со статической, в груви поддерживается динамическая типизация, вместо String a = «a» можно смело писать def a = «a» или даже def map = [‘one’:1, ‘two’:2, ‘list’ = [1,false]]
  • Есть замыкания, для которых можно динамически определить контекст исполнения. Те самые блоки android <. >принимают замыкания и потом исполняют их для какого-то объекта.
  • Есть интерполяция строк «$a, $» , multiline-строки «»»yep, $«»» , а обычные java-строки обрамляются одинарными кавычками: ‘text’
  • Есть подобие extension-методов. В стандартной коллекции языка уже есть методы типа any, every, each, findAll. Лично мне названия методов кажутся непривычными, но главное что они есть.
  • Вкусный синтаксический сахар, код становится намного короче и проще. Можно не писать скобки вокруг аргументов функции, для объявления списков и хеш-табличек приятный синтаксис: [a,b,c], Android studio gradle examples

В общем, почему языки типа Python/Javascript взлетели, а Groovy нет — для меня загадка. Для своего времени, когда в java даже лямбд не было, а альтернативы типа kotlin/scala только-только появлялись или ещё не существовали, Groovy должен был выглядеть реально интересным языком.

Именно гибкость синтаксиса groovy и динамическая типизация позволила в gradle создавать лаконичные DSL.

Сейчас в официальной документации Gradle примеры продублированы на Kotlin, и вроде как планируется переходить на него, но код уже не выглядит таким простым и становится больше похожим на обычный код:

Впрочем, переименование в Kradle пока не планируется.

Стадии сборки

Их делят на инициализацию, конфигурацию и выполнение.

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

Возможно, это неочевидно, но вышеуказанное будет тормозить инициализацию. Чтобы не заниматься копированием файлов при каждой инициализации, нужно в задаче использоваль блок doLast <. >или doFirst <. >— тогда код завернётся в замыкание и его позовут в момент выполнения задачи.

В старых примерах вместо doLast можно встретить оператор , но от него потом отказались из-за неочевидности поведения.

tasks.all

Что забавно, с помощью doLast и doFirst можно навешивать какие-то действия на любые задачи:

IDE подсказывает, что у tasks есть метод whenTaskAdded(Closure . ) , но метод all(Closure . ) работает намного интереснее — замыкание вызывается для всех существующих задач, а так же на новых задачах при их добавлении.

Создадим задачу, которая распечатает зависимости всех задач:

Если tasks.all<> вызвать во время выполнения (в блоке doLast ), то мы увидим все задачи и зависимости.
Если сделать то же самое без doLast (т.е., во время инициализации), то у распечатанных задач может не хватать зависимостей, так как они ещё не были добавлены.

Ах да, зависимости! Если другая задача должна зависеть от результатов выполнения нашей, то стоит добавить зависимость:

inputs, outputs и инкрементальная сборка

Обычная задача будет вызываться каждый раз. Если указать, что задача на основе файла А генерирует файл Б, то gradle будет пропускать задачу, если эти файлы не изменились. Причём gradle проверяет не дату изменения файла, а именно его содержимое.

Аналогично можно указать папки, а так же какие-то значения: inputs.property(name, value) .

task description

При вызове ./gradlew tasks —all стандартные задачи имеют красивое описание и как-то сгруппированы. Для своих задач это добавляется очень просто:

task.enabled

можно «выключить» задачу — тогда её зависимости будут всё равно вызваны, а она сама — нет.

несколько проектов (модулей)

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

Ещё пример: при публикации проекта с помощью jitpack в рутовом проекте описывается, с какими настройками публиковать дочерний модуль, который про факт публикации может даже не подозревать.

Дочерние модули указываются в settings.gradle:

Подробнее про зависимости между проектами можно почитать здесь

buildSrc

Если кода в build.gradle много или он дублируется, его можно вынести в отдельный модуль. Нужна папка с магическим именем buildSrc , в которой можно расположить код на groovy или java. (ну, вернее, в buildSrc/src/main/java/com/smth/ код, тесты можно добавить в buildSrc/src/test ). Если хочется что-то ещё, например, написать свою задачу на scala или использовать какие-то зависимости, то прямо в buildSrc надо создать build.gradle и в нём указать нужные зависимости/включить плагины.

К сожалению, с проектом в buildSrc IDE может тупить c подсказками, там придётся писать импорты и классы/задачи оттуда в обычный build.gradle тоже придётся импортировать. Написать import com.smth.Taskname — не сложно, просто надо это помнить и не ломать голову, почему задача из buildSrc не найдена).

По этой причине удобно сначала написать что-то работающее прямо в build.gradle , и только потом переносить код в buildSrc .

Свой тип задачи

Задача наследуется от DefaultTask , в которой есть много-много полей, методов и прочего. Код AbstractTask, от которой унаследована DefaultTask.

  • вместо ручного добавления inputs и outputs можно использовать поля и аннотации к ним: @Input, @OutputFile и т.п.
  • метод, который будут запускать при выполнении задачи: @TaskAction .
  • удобные методы типа copy всё ещё можно вызвать, но придётся их явно вызывать для проекта: project.copy

Когда для нашей задачи кто-то в build.gradle пишет

у задачи вызывается метод configure(Closure) .

Я не уверен, что это правильных подход, но если у задачи есть несколько полей, взаимное состояние которых сложно контролировать геттерами-сеттерами, то кажется вполне удобным переопределить метод следующим образом:

Причём даже если написать

то метод configure всё равно будет вызван.

Свой плагин

Подобно задаче, можно написать свой плагин, который будет что-то настраивать или создавать задачи. Например, происходящее в android <. >— полностью заслуга тёмной магии андроид плагина, который вдобавок создаёт целую кучу задач типа app:assembleDevelopDebug на все возможные сочетания flavor/build type/dimenstion. Ничего сложного в написании своего плагина нет, для лучшего понимания можно посмотреть код других плагинов.

Есть ещё третья ступенька — можно код расположить не в buildSrc , а сделать его отдельным проектом. Потом с помощью https://jitpack.io или ещё чего-то опубликовать плагин и подключать его аналогично остальным.

The end

В примерах выше могут быть опечатки и неточности. Пишите в личку или отмечайте с ctrl+enter — исправлю. Конкретные примеры лучше брать из документации, а на эту статью смотреть как на списочек того «как можно делать».

Источник

Читайте также:  Загрузить карты для навигатора андроид
Оцените статью