Android TOML. Просто о каталогах зависимостей в Android Studio
Всем привет!
Меня зовут Евгений и я Android-разработчик. Сегодня хотел бы поделиться своими знаниями и наблюдениями относительно нового способа добавления зависимостей в проекты, созданные на базе Android Studio.
Предисловие
29.02.2024 вышла в stable новая версия Android Studio — Iguana. Вместе со сменой названия версии появилась возможность формировать зависимости в удобные каталоги формата .toml.
Актуальная версия Android Studio
Лично для меня это было неожиданностью, так как об изменениях в новой версии я, в этот раз, не прочитал, а создание проектов «с нуля» у меня происходит редко, как правило, работаю над уже существующими проектами.
Но удивление было недолгим, после первого взгляда на блок зависимостей в новом проекте, стало понятно, что с этим можно разобраться и мне это уже знакомо. Подобное разделение зависимостей я уже встречал в крупных проектах и было предсказуемо, что однажды это станет стандартом для новых проектов в Android Studio.
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
}
Хочется отметить, что блок добавления зависимостей стал выглядеть лучше, чем было до этого.
Разбираемся
Выбираем любую зависимость, переходим по ней (ctrl + ЛКН на Windows и Cmd + ЛКН на Mac OS) и попадаем в каталог зависимостей libs.versions.toml. Выглядит он так:
Слева видим, что libs.versions.toml лежит в Gradle Scripts.
Каталог содержит три раздела:
[versions]
[libraries]
[plugins]
Из названий понятно, что в первом разделе нужно указать версию зависимости или плагина, во втором — зависимость для библиотек, в третьем каталоге указываем зависимость для плагинов.
Обращаю ваше внимание на то, что все необходимые данные указываем в формате String.
Если с добавлением версии плагина или библиотеки в резделе [versions]все очевидно, то формат добавления самой зависимости не так очевиден. Предлагаю добавить зависимость библиотеки room из пакета androidx сначала старым способом, а затем новым.
Добавляем зависимости
Старый способ
Если бы мы этот делали старым способом, то выглядело бы это так:
Добавляем процессор аннотаций KSP в build.gradle.kts на уровне проекта, синхронизируем проект
plugins {
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.jetbrainsKotlinAndroid) apply false
id("com.google.devtools.ksp") version "1.8.10-1.0.9" apply false
}
Добавляем плагин для KSP в build.gradle.kts на уровне модуля (при создании нового проекта, по умолчанию, это модуль App), синхронизируем проект
plugins { alias(libs.plugins.androidApplication) alias(libs.plugins.jetbrainsKotlinAndroid) id("com.google.devtools.ksp") }
В блоке dependencies добавляем зависимости для библиотеки Room, annotationProcessor для работы с аннотациями Room и сам KSP для их обработки.
dependencies { val room_version = "2.6.1" implementation("androidx.room:room-runtime:$room_version") annotationProcessor("androidx.room:room-compiler:$room_version") ksp("androidx.room:room-compiler:$room_version") implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) implementation(libs.material) implementation(libs.androidx.activity) implementation(libs.androidx.constraintlayout) testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) }
Как мы видим, старый способ добавления зависимостей прекрасно работает с новым способом.
Новый способ
Для начала, разберем новый формат добавления зависимостей.
Как помним из примера выше, старым способом зависимость добавляется в формате
implementation("androidx.room:room-runtime:2.6.1)
Здесь мы видим:
implementation — сам метод, в который добавляется зависимость
androidx.room — пакет, в котором лежит библиотека
room-runtime — название библиотеки
2.6.1 — версия библиотеки
Точно таким же способом она разделена и в новом каталоге .toml:
Схема нового формата для добавления зависимостей и плагинов в .toml
На схеме видим, что в разделе [libraries] мы добавили строчку с зависимостью для библитеки Room и ее версию в разделе [versions].
Название зависимости — то, как мы называем свою зависимость. Имя произвольное, принято указывать с использованием kebab-case, то есть, через »-» (дефис или тире).
Далее в функциональных (фигурных) скобках указываем параметр group — то, как будет группироваться зависимость. Здесь нужно указать пакет библиотеки. Например, Room входит в пакет androix.room, соответственно, указываем именно так. Двоеточие ставить не нужно.
Следом указываем параметр name — это название библиотеки.
И в последнюю очередь, в параметр version.ref — версию библиотеки. Само же название версии в разделе [versions] принято указывать в camelCase. Синхронизируем проект.
Переходим в build.gradle.kts на уровне проекта и добавляем плагин KSP (обратите внимание, на предыдщем шаге он добавлен в [plugins]). Синхронизируем проект
plugins {
alias(libs.plugins.androidApplication) apply false
alias(libs.plugins.jetbrainsKotlinAndroid) apply false
alias(libs.plugins.ksp) apply false
}
Переходим в build.gradle.kts на уровне модуля и добавляем плагин KSP. Синхронизируем проект.
plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.jetbrainsKotlinAndroid)
alias(libs.plugins.ksp)
}
В этом же файле добавляем нужные нам зависимости, указывая путь к ним в блоке dependencies:
dependencies {
implementation(libs.androidx.room)
annotationProcessor(libs.androidx.room.annotation.processor)
ksp(libs.androidx.room.annotation.processor)
Обращаю ваше внимание на то, что несмотря на то, что название зависимостей в каталоге .toml мы добавляли через дефис, путь к файлам в build.gradle.kts нужно добавлять через точку.
Проверяем работу:
package com.gorovoyeg.newproject
import androidx.room.ColumnInfo
import androidx.room.Dao
import androidx.room.Database
import androidx.room.Entity
import androidx.room.PrimaryKey
import androidx.room.Query
import androidx.room.RoomDatabase
@Database(entities = [TestEntity::class] , version = 1, exportSchema = false)
abstract class TestDatabase: RoomDatabase() {
abstract fun testDao(): TestDao
}
@Dao
interface TestDao {
@Query("SELECT * FROM test_entity")
fun testFunAll(): TestEntity
}
@Entity(tableName = "test_entity")
data class TestEntity(
@PrimaryKey(autoGenerate = true) val testId: Int,
@ColumnInfo(name = "test_name" ) val testName: String
)
Все работает отлично.
Подводим итоги
Как я и подкчеркнул в начале статьи — нововведение по добавлению зависимостей через каталог libs.versions.toml в новой версии Android Studio это вполне очевидная и предсказуемая мера со стороны Google. Для крупных действующих проектов это нововведение уже неактульно, так как многие самостоятельно уже разделяют зависимости более понятным и удобным способом, чем добавление зависимостей и их версий в блок dependencies в build.gradle. Тем не менее, считаю, что это приятное новое дополнение для разработчиков, которые стремятся к порядку в коде.
Использовать новый подход или нет — оставляю решение на ваше усмотрение. Лично я буду :-)
Спасибо за внимание.