Avatar ·

Библиотека Safe Args не генерирует класс Directions после обновления Gradle

Всем привет! Я новичок в Kotlin и Android-разработке, и столкнулся с очень странной проблемой. Использую Navigation Component с Safe Args для передачи данных между фрагментами. До недавнего времени всё работало отлично, но после того как я обновил Gradle и плагины (с версии 7.x на 8.x), библиотека Safe Args перестала генерировать классы Directions. У меня есть nav_graph.xml с двумя фрагментами: FirstFragment и SecondFragment. Между ними определён action с аргументом userId. Раньше я мог использовать FirstFragmentDirections.actionFirstToSecond(userId), но теперь компилятор пишет, что не может найти класс FirstFragmentDirections. При этом классы Args (например, SecondFragmentArgs) генерируются нормально, а Directions — нет. Вот мой build.gradle (app-level): ``` plugins { id("com.android.application") id("org.jetbrains.kotlin.android") id("androidx.navigation.safeargs.kotlin") } android { compileSdk 34 ... } dependencies { implementation("androidx.navigation:navigation-fragment-ktx:2.7.7") implementation("androidx.navigation:navigation-ui-ktx:2.7.7") } ``` Пробовал чистить проект (Build -> Clean Project), пересобирать, делать Invalidate Caches. Ничего не помогает. Классы Directions просто не появляются. Может, кто-то сталкивался? Что я делаю не так? <<>>

Почему Safe Args не генерирует Directions после обновления Gradle?

Проблема, с которой вы столкнулись, довольно распространена среди разработчиков, переходящих на новые версии Gradle и AGP (Android Gradle Plugin). Основная причина — изменение механизма генерации кода в AGP 8.x. Safe Args использует обработку аннотаций, но в новых версиях Gradle она может быть настроена иначе, или плагин Safe Args может конфликтовать с другими плагинами.

Решение: проверка конфигурации плагина Safe Args

  1. Убедитесь, что плагин Safe Args подключен корректно. В вашем build.gradle (app-level) должно быть:
    plugins {
        id("androidx.navigation.safeargs.kotlin")
    }

    Обратите внимание: если вы используете Kotlin DSL (build.gradle.kts), синтаксис может отличаться:

    plugins {
        id("androidx.navigation.safeargs.kotlin")
    }

  2. Проверьте версию Navigation Component. Safe Args должен быть совместим с версией navigation-fragment-ktx. Рекомендую использовать версию 2.7.7 или новее (на момент написания ответа — 2.8.0). Убедитесь, что в вашем корневом build.gradle (project-level) указана версия плагина:
    plugins {
        id("androidx.navigation.safeargs.kotlin") version "2.7.7" apply false
    }
  3. Очистите и пересоберите проект. Иногда помогает не просто Clean, а полное удаление папок build:
    • Закройте Android Studio.
    • Удалите папки .gradle, build и app/build.
    • Откройте проект заново и выполните File -> Sync Project with Gradle Files, затем Build -> Rebuild Project.
  4. Проверьте наличие конфликтов с другими плагинами. Если у вас подключены плагины kotlin-kapt или kotlin-parcelize, они могут мешать. Попробуйте временно отключить их и пересобрать проект.
  5. Альтернатива: используйте явную обработку аннотаций. В AGP 8.x рекомендуется явно указывать обработчики аннотаций. Добавьте в build.gradle:
    android {
        ...
        buildFeatures {
            viewBinding = true
        }
        kapt {
            correctErrorTypes = true
        }
    }

    И убедитесь, что у вас нет дублирования плагинов (например, id("kotlin-kapt") не должен конфликтовать с safeargs.kotlin).

Пример рабочей конфигурации (build.gradle.kts)

// project-level build.gradle.kts
plugins {
    id("com.android.application") version "8.2.0" apply false
    id("org.jetbrains.kotlin.android") version "1.9.22" apply false
    id("androidx.navigation.safeargs.kotlin") version "2.7.7" apply false
}

// app-level build.gradle.kts
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("androidx.navigation.safeargs.kotlin")
}

android {
    namespace = "com.example.myapp"
    compileSdk = 34

    defaultConfig {
        applicationId = "com.example.myapp"
        minSdk = 24
        targetSdk = 34
        versionCode = 1
        versionName = "1.0"
    }
}

dependencies {
    implementation("androidx.navigation:navigation-fragment-ktx:2.7.7")
    implementation("androidx.navigation:navigation-ui-ktx:2.7.7")
}

После этих шагов выполните Build -> Rebuild Project. Если классы Directions всё ещё не генерируются, проверьте ваш nav_graph.xml — убедитесь, что action определён корректно и имеет уникальный ID.

<<>>

Альтернативный подход: ручная генерация классов Safe Args

Если стандартный плагин Safe Args продолжает отказываться работать, можно использовать ручную настройку генерации через kapt или ksp. Это особенно актуально для проектов с нестандартной конфигурацией Gradle.

Добавьте в build.gradle (app-level) следующее:

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("kotlin-kapt")
}

dependencies {
    implementation("androidx.navigation:navigation-fragment-ktx:2.7.7")
    implementation("androidx.navigation:navigation-ui-ktx:2.7.7")
    kapt("androidx.navigation:navigation-safe-args-generator:2.7.7")
}

Затем явно укажите в android блоке:

android {
    ...
    kapt {
        arguments {
            arg("navArgs", "true")
        }
    }
}

После синхронизации и пересборки классы Directions должны появиться. Этот метод обходит проблемы с плагином, но требует явного указания версии генератора.

Важно: Если вы используете KSP (Kotlin Symbol Processing) вместо kapt, замените kapt на ksp и добавьте плагин com.google.devtools.ksp. Однако Safe Args официально поддерживает только kapt, поэтому этот способ может работать нестабильно.