Подпроекты Android с Kotlin DSL

Я работаю над переносом файлов сборки Gradle на Kotlin DSL, и у меня возникла проблема.

На моем родительском build.gradle у меня есть следующий фрагмент кода



buildscript {
  repositories {
    google()
    mavenCentral()
  }
  dependencies {
    classpath 'com.android.tools.build:gradle:3.4.2'
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${Version.kotlin}"
  }
}

allprojects {
  repositories {
    google()
    mavenCentral()
  }
}

subprojects {
  afterEvaluate { project ->

    if (project.plugins.findPlugin('com.android.application') ?:
      project.plugins.findPlugin('com.android.library')) {

      android {
        compileSdkVersion = Android.SDK_COMPILE
        defaultConfig {
          minSdkVersion Android.SDK_MIN
          targetSdkVersion Android.SDK_TARGET
          versionCode = Android.VERSION_CODE
          versionName = Android.VERSION_NAME
        }
        ...
      } 
    }
  }
}

Это позволяет мне настраивать только в одном месте все модули, которые являются приложениями или библиотеками Android.

Однако, когда я перешел на kotlin, похоже, это не сработало:


buildscript {
  repositories {
    google()
    mavenCentral()
  }
  dependencies {
    classpath(Dependency.androidGradle)
    classpath(Dependency.kotlinGradle)
  }
}

allprojects {
  repositories {
    google()
    mavenCentral()
  }
}

subprojects {
  afterEvaluate {

    if (project.plugins.findPlugin("com.android.application") != null || 
        project.plugins.findPlugin("com.android.library") != null) {

      android { <<<<------------ Unresolved reference: android
        compileSdkVersion(Android.SDK_COMPILE)
        defaultConfig {
          minSdkVersion(Android.SDK_MIN)
          targetSdkVersion(Android.SDK_TARGET)
          versionCode = Android.VERSION_CODE
          versionName = Android.VERSION_NAME
        }
        ...
      }
    }
  }
}

Ошибка Unresolved reference: android, и похоже, что блок android{} не распознается компилятором сценария.

Моя теория заключается в том, что проверки if для типа подпроекта недостаточно, и мне, возможно, придется преобразовать или получить ссылку на какой-то объект, в котором я могу вызвать блок android{}, но, честно говоря, я не знаю достаточно.

Какие-нибудь подсказки?


person Robert Estivill    schedule 23.08.2019    source источник
comment
Почему вы все это оборачиваете в afterEvaluate блок? За исключением того, что вы возитесь с задачами компиляции или что-то еще, вам не нужен блок afterEvaluate. Просто используйте project.plugins.withId("<plugin-id>") { ... }   -  person efemoney    schedule 25.08.2019
comment
Вы найдете решение, как получить доступ к android внутри блока подпроектов gradle kotlin-dsl?   -  person Lê Khánh Vinh    schedule 06.10.2019


Ответы (1)


Gradle Kotlin DSL определяет зависимости для каждого скрипта от пути к классам gradle и применяемых подключаемых модулей. Вот почему рекомендуется использовать блок plugins { ... } в Kotlin DSL.

Вам нужно добавить плагины android и kotlin в корневой каталог, не применяя его.

plugins {
  id("<android-plugin>") version "<plugin-version>" apply false
  id("<kotlin-plugin>") version "<plugin-version>" apply false
}

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

subprojects {

  // BasePlugin is the common superclass of the AppPlugin and LibraryPlugin which are the plugin classes that "com.android.application" and "com.android.library" apply
  plugins.withType<BasePlugin> {

    // BaseExtension is the common superclass of the AppExtension and LibraryExtension which are the extension classes registered by the two plugins to the name "android"
    configure<BaseExtension> {

      // This block is typed correctly
      defaultConfig {
        // ...
      }
    }
  }
}
person efemoney    schedule 25.08.2019
comment
Спасибо за Ваш ответ. Все это имеет смысл, скоро попробую! - person Robert Estivill; 25.08.2019
comment
Это было сложно, но, наконец, все заработало. Для второй части кода мне пришлось использовать plugins.withType(BasePlugin::class.java) вместо plugins.withType(BasePlugin) - person Alex Burdusel; 09.09.2019
comment
у вас есть образец кода, чтобы применить это? Я пытаюсь переместить модуль build.gradle.kts в корневой build.gradle.kts с помощью подпроектов - person Lê Khánh Vinh; 05.10.2019
comment
@AlexBurdusel plugins.withType ‹BasePlugin› - person Сергей; 04.09.2020