Всем привет!
Меня зовут Евгений и я Android-разработчик. Сегодня хотел бы поделиться своими знаниями и наблюдениями относительно нового способа добавления зависимостей в проекты, созданные на базе Android Studio.
Предисловие
29.02.2024 вышла в stable новая версия Android Studio - Iguana. Вместе со сменой названия версии появилась возможность формировать зависимости в удобные каталоги формата .toml.

Лично для меня это было неожиданностью, так как об изменениях в новой версии я, в этот раз, не прочитал, а создание проектов «с нуля» у меня происходит редко, как правило, работаю над уже существующими проектами.
Но удивление было недолгим, после первого взгляда на блок зависимостей в новом проекте, стало понятно, что с этим можно разобраться и мне это уже знакомо. Подобное разделение зависимостей я уже встречал в крупных проектах и было предсказуемо, что однажды это станет стандартом для новых проектов в 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. Выглядит он так:

Каталог содержит три раздела:
[versions]
[libraries]
[plugins]
Из названий понятно, что в первом разделе нужно указать версию зависимости или плагина, во втором - зависимость для библиотек, в третьем каталоге указываем зависимость для плагинов.
Обращаю ваше внимание на то, что все необходимые данные указываем в формате String.
Если с добавлением версии плагина или библиотеки в резделе [versions] все очевидно, то формат добавления самой зависимости не так очевиден. Предлагаю добавить зависимость библиотеки room из пакета androidx сначала старым способом, а затем новым.
Добавляем зависимости
Старый способ
Если бы мы этот делали старым способом, то выглядело бы это так:
Добавляем процессор аннотаций KSP в build.gradle.kts на уровне проекта, синхронизируем проект
plugins { ... id("com.google.devtools.ksp") version "1.8.10-1.0.9" apply false }
Добавляем плагин для KSP в build.gradle.kts на уровне модуля (при создании нового проекта, по умолчанию, это модуль App), синхронизируем проект
plugins { ... 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("androidx.room:room-runtime:2.6.1)
Здесь мы видим:
implementation - сам метод, в который добавляется зависимость
androidx.room - пакет, в котором лежит библиотека
room-runtime - название библиотеки
2.6.1 - версия библиотеки
Точно таким же способом она разделена и в новом каталоге .toml:

На схеме видим, что в разделе [libraries] мы добавили строчку с зависимостью для библитеки Room и ее версию в разделе [versions].
Название зависимости - то, как мы называем свою зависимость. Имя произвольное, принято указывать с использованием kebab-case, то есть, через "-" (дефис или тире).
Далее в функциональных (фигурных) скобках указываем параметр group - то, как будет группироваться зависимость. Здесь нужно указать пакет библиотеки. Например, Room входит в пакет androix.room, соответственно, указываем именно так. Двоеточие ставить не нужно.
Следом указываем параметр name - это название библиотеки.
И в последнюю очередь, в параметр version.ref - версию библиотеки. Само же название версии в разделе [versions] принято указывать в camelCase. Синхронизируем проект.
Переходим в build.gradle.kts на уровне проекта и добавляем плагин KSP (обратите внимание, на предыдщем шаге он добавлен в [plugins]). Синхронизируем проект
plugins { ... alias(libs.plugins.ksp) apply false }
Переходим в build.gradle.kts на уровне модуля и добавляем плагин KSP. Синхронизируем проект.
plugins { ... 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. Тем не менее, считаю, что это приятное новое дополнение для разработчиков, которые стремятся к порядку в коде.
Использовать новый подход или нет - оставляю решение на ваше усмотрение. Лично я буду :-)
Спасибо за внимание.
