Groovy から KTS へのビルド構成の移行
記事ディレクトリ
序文
開発者としてAndroid
、私はオブジェクト指向プログラミングに慣れており、IDEA
提供されているさまざまな補助的な開発ショートカット機能にも慣れています。
まあ、なじみのない、従来の構文を使用したスクリプトは、Groovy
常に私のものでした。
Kotlin DSL
Kotlin で記述されたコードはより読みやすく、Kotlin はより優れたコンパイル時のチェックと IDE サポートを提供するため、feel の出現は私たちに合わせて作られています。
名詞の概念説明
-
Gradle : 自動ビルド ツール. 並行製品:
Maven
. -
Groovy
JVM byte code
:互換性のあるプラットフォームにコンパイルされた言語Java
。 -
DSL :
Domain Specific Language
、ドメイン固有言語。 -
Groovy DSL :
Gradle
API は Java であり、Groovy DSL
その上にスクリプト言語です.Groovy DS
スクリプト ファイルのサフィックス:.gradle
. -
KTS : Kotlin スクリプトを指します。これは、 Gradle がビルド構成ファイルで使用するKotlin 言語の形式です。Kotlin スクリプトは、コマンドラインから実行できるKotlin コードです。
-
Kotlin DSL : 主にAndroid Gradle プラグイン Kotlin DSLを指し、基盤となる Gradle Kotlin DSLを指す場合もあります。
Groovy からの移行について説明する場合、「KTS」と「Kotlin DSL」という用語は同じ意味で使用されます。つまり、「Android プロジェクトを Groovy から KTS に変換する」と「Android プロジェクトを Groovy から Kotlin DSL に変換する」は、実際には同じことを意味します。
Groovy と KTS の比較
タイプ | コトリン | グルーヴィー |
---|---|---|
自動コード補完 | サポート | サポートしません |
タイプセーフか | はい | いいえ |
ソースコードのナビゲーション | サポート | サポートしません |
リファクタリング | 自動関連付け | 手動修正 |
アドバンテージ:
- 使用できます
Kotlin
。開発者はこの言語に慣れていて、好む可能性があります。 IDE
サポートの改善、オートコンプリートのヒント、リファクタリングimports
など。- 型の安全性:
Kotlin
静的に型付けされます。 - 一度にすべてを移行する必要はありません。2 つの言語のスクリプトが共存し、相互に呼び出すことができます。
短所と既知の問題:
-
現在、Adopting
KTS
のGroovy
Adopting のビルド速度よりも遅くなる可能性があります (セルフテストの約 40% (約 8 秒) の小さなデモに時間がかかります)。 -
Project Structure
エディターは、ライブラリー名またはバージョンのbuildSrc
フォルダー。 -
KTS
ファイルは現在、プロジェクト ビューでテキスト ヒントを提供していません。
Groovy から KTS への Android ビルド構成の移行
準備
-
Groovy
文字列は一重引用'string'
符または"string"
が、二重引用符Kotlin
は必須です"string"
。 -
Groovy
関数を呼び出すときは括弧を省略できますが、括弧はKotlin
常に。 -
Gradle Groovy DSL
プロパティを代入するときは=
代入が、Kotlin
代入演算子は常に必要です。
したがって、KTS
次のように均一に行う必要があります。
- 引用符を統一するには、二重引用符を使用します。
- 関数呼び出しとプロパティの割り当てを明確にします (それぞれ括弧と代入演算子を使用)。
スクリプトファイル名
Groovy DSLスクリプト ファイルは、.gradle
ファイル。
Kotlin DSLスクリプト ファイルは、.gradle.kt
s ファイル拡張子を使用します。
ファイルを 1 つずつ移行する
プロジェクト内のGroovy build
ファイル、KTS build
プロジェクトを に変換する簡単な方法は、最初に単純なファイル (たとえば) を選択し、名前を に変更し、その内容を に変換することです。その後、各ファイルを。KTS
build
settings.gradle
settings.gradle.kts
KTS
build
カスタム タスク
Koltin
静的に型付けされた言語と動的な言語であるためGroovy
、前者は型安全であり、その性質の違いはタスクの作成と構成に明確に反映されます。詳細については、公式の Gradle 移行チュートリアルを参照してください。
// groovy
task clean(type: Delete) {
delete rootProject.buildDir
}
// kotiln-dsl
tasks.register("clean", Delete::class) {
delete(rootProject.buildDir)
}
val clean by tasks.creating(Delete::class) {
delete(rootProject.buildDir)
}
open class GreetingTask : DefaultTask() {
var msg: String? = null
@TaskAction
fun greet() {
println("GreetingTask:$msg")
}
}
val msg by tasks.creating(GreetingTask::class) {
}
val testTask: Task by tasks.creating {
doLast {
println("testTask:Run")
}
}
val testTask2: Task = task("test2") {
doLast {
println("Hello, World!")
}
}
val testTask3: Task = tasks.create("test3") {
doLast {
println("testTask:Run")
}
}
plugins
コードブロックを使用する
build
ファイルでplugins
コードと、IDE
ビルドが失敗した場合でもコンテキスト情報を取得できます。IDE
この情報を使用して、コード補完を実行したり、KTS
ファイルの。
コードで、命令apply plugin
を宣言plugins
ブロックに置き換えます。Groovy
次のコードは...
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'androidx.navigation.safeargs.kotlin'
KTS では次のコードになります。
plugins {
id("com.android.application")
id("kotlin-android")
id("kotlin-kapt")
id("androidx.navigation.safeargs.kotlin")
}
plugins
コードブロックの詳細については、 Gradle の移行ガイドを参照してください。
注:plugins
コード ブロックは、Gradle プラグイン ポータルまたはpluginManagement
コード。プラグインがプラグイン ポータルに存在しないbuildScript
依存関係、それらのプラグインを Kotlin で使用しapply
て適用する必要があります。例えば:
apply(plugin = "kotlin-android")
apply {
from("${
rootDir.path}/config.gradle")
from("${
rootDir.path}/version.gradle.kts")
}
詳細については、Gradle のドキュメントを参照してください。
plugins {}
関数よりもブロックを使用することを強くお勧めしますapply()
。
Kotlin DSL
の静的コンテキストでの作業を容易にするための 2 つの重要なベスト プラクティスがあります。
plugins {}
ブロックを使用- ローカル ビルド ロジックをビルドのbuildSrcディレクトリに配置します。
プラグイン {} ブロックは、ビルド スクリプトを宣言的に維持して最大限に活用することを目的としています
Kotlin DSL
。buildSrcプロジェクトを使用するということは、ビルド ロジックを、テストが容易で優れた IDE サポートを備えた共有ネイティブ プラグインと規約に編成することです。
依存関係管理
共通の依存関係
// groovy
implementation project(':library')
implementation 'com.xxxx:xxxx:8.8.1'
// kotlin
implementation(project(":library"))
implementation("com.xxxx:xxx:8.8.1")
フリーツリー
// groovy
implementation fileTree(include: '*.jar', dir: 'libs')
//kotlin
implementation(fileTree(mapOf("include" to listOf("*.jar"), "dir" to "libs")))
特別なタイプ ライブラリの依存関係
//groovy
implementation(name: 'splibrary', ext: 'aar')
//kotlin
implementation (group="",name="splibrary",ext = "aar")
ビルドバリアント
明示的および暗黙的buildTypes
Kotlin DSL では、一部buildTypes
( やdebug
などrelease,
) が暗黙的に提供されます。ただし、buildTypes
その他は手動で作成する必要があります。
たとえば、Groovy ではdebug
、 、release
およびstaging
buildTypes
:
buildTypes
debug {
...
}
release {
...
}
staging {
...
}
KTS では、 とdebug
のみがrelease
buildTypes
暗黙的に提供されますstaging
がは手動で作成する必要があります。
buildTypes
getByName("debug") {
...
}
getByName("release") {
...
}
create("staging") {
...
}
例えば
Grovvy
書く:
productFlavors {
demo {
dimension "app"
}
full {
dimension "app"
multiDexEnabled true
}
}
buildTypes {
release {
signingConfig signingConfigs.signConfig
minifyEnabled true
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
minifyEnabled false
debuggable true
}
}
signingConfigs {
release {
storeFile file("myreleasekey.keystore")
storePassword "password"
keyAlias "MyReleaseKey"
keyPassword "password"
}
debug {
...
}
}
kotlin-KTL
書く:
productFlavors {
create("demo") {
dimension = "app"
}
create("full") {
dimension = "app"
multiDexEnabled = true
}
}
buildTypes {
getByName("release") {
signingConfig = signingConfigs.getByName("release")
isMinifyEnabled = true
isDebuggable = false
proguardFiles(getDefaultProguardFile("proguard-android.txtt"), "proguard-rules.pro")
}
getByName("debug") {
isMinifyEnabled = false
isDebuggable = true
}
}
signingConfigs {
create("release") {
storeFile = file("myreleasekey.keystore")
storePassword = "password"
keyAlias = "MyReleaseKey"
keyPassword = "password"
}
getByName("debug") {
...
}
}
アクセス構成
gradle.properties
通常、署名情報、バージョン情報、およびその他の構成は に記述しますgradle.properties
. kotlin-dsl では、次の方法でそれらにアクセスできます:
rootProject.extra.properties
project.extra.properties
rootProject.properties
properties
System.getProperties()
System.getProperties()
利用制限が増える
- パラメータ名は
systemProp.xxx
次の形式に従う必要があります (例:systemProp.kotlinVersion=1.3.72
)。 - 現在実行されているタスクに関連しています(
> Configure project :buildSrc
結果> Configure project :
は異なります。後者はgradle.properties
タスク内のデータを取得できません)。
local.properties
プロジェクトlocal.properties
ファイルを取得する
gradleLocalProperties(rootDir)
gradleLocalProperties(projectDir)
システム環境変数の値を取得する
val JAVA_HOME:String = System.getenv("JAVA_HOME") ?: "default_value"
Extについて
Google が公式に推奨するGradle 構成のベスト プラクティスは、プロジェクトの最も外側の build.gradle ファイルext
のコード ブロックでプロジェクト全体のプロパティを定義し、これらのプロパティをすべてのモジュール間で共有することです。たとえば、通常、のバージョン番号を保存します。このように依存関係。
// build.gradle
ext {
compileSdkVersion = 28
buildToolsVersion = "28.0.3"
supportLibVersion = "28.0.0"
...
}
ただし、IDE のサポートがないため (ジャンプ ビュー、グローバル リファクタリングなどはサポートされていません)、実際の使用感は良くありません。
の代わりに使用KTL
extra
Groovy
ext
// The extra object can be used for custom properties and makes them available to all
// modules in the project.
// The following are only a few examples of the types of properties you can define.
extra["compileSdkVersion"] = 28
// You can also create properties to specify versions for dependencies.
// Having consistent versions between modules can avoid conflicts with behavior.
extra["supportLibVersion"] = "28.0.0"
android {
// Use the following syntax to access properties you defined at the project level:
// rootProject.extra["property_name"]
compileSdkVersion(rootProject.extra["sdkVersion"])
// Alternatively, you can access properties using a type safe delegate:
val sdkVersion: Int by rootProject.extra
...
compileSdkVersion(sdkVersion)
}
...
dependencies {
implementation("com.android.support:appcompat-v7:${
rootProject.ext.supportLibVersion}")
...
}
build.gralde
のデータには、 inを使用してext
アクセスできます。build.gradle.kts
extra
生成された apk の名前を変更し、BuildConfig で apk がサポートする cpu アーキテクチャを追加します。
val abiCodes = mapOf("armeabi-v7a" to 1, "x86" to 2, "x86_64" to 3)
android.applicationVariants.all {
val buildType = this.buildType.name
val variant = this
outputs.all {
val name =
this.filters.find {
it.filterType == com.android.build.api.variant.FilterConfiguration.FilterType.ABI.name }?.identifier
val baseAbiCode = abiCodes[name]
if (baseAbiCode != null) {
//写入cpu架构信息
variant.buildConfigField("String", "CUP_ABI", "\"${
name}\"")
}
if (this is com.android.build.gradle.internal.api.ApkVariantOutputImpl) {
//修改apk名称
if (buildType == "release") {
this.outputFileName = "KotlinDSL_${
name}_${
buildType}.apk"
} else if (buildType == "debug") {
this.outputFileName = "KotlinDSL_V${
variant.versionName}_${
name}_${
buildType}.apk"
}
}
}
}
buildSrc
言語構築を行う場合、グローバル変数制御としてGroovy
抽出することが多く、拡張機能を使用する必要がありますが、弊社のシステムでは、グローバル制御を使用したい場合は、それを推奨する必要があります。version_config.gradle
ext
Gradle Kotlin DSL
buildSrc
複雑なビルド ロジックは、多くの場合、カスタム タスクまたはバイナリ プラグインとしてパッケージ化するのに適しています。カスタム タスクとプラグインの実装は、ビルド スクリプトに存在してはなりません。buildSrc
そうすれば、複数の独立したプロジェクト間でコードを共有する必要がなくなり、コードを非常に便利に使用できます。
buildSrc
ビルド ディレクトリとして扱われます。コンパイラがディレクトリを検出すると、Gradle
このコードを自動的にコンパイルおよびテストし、ビルド スクリプトのクラスパスに配置します。
- 最初にディレクトリを作成します
buildSrc
。- このディレクトリにファイルを作成します
build.gradle.kts
。- ディレクトリを作成します
buildSrc/src/main/koltin
。Dependencies.kt
バージョン管理クラスとしてこのディレクトリにファイルを作成します。
buildSrc
次の点に注意してくださいbuild.gradle.kts
。
plugins {
`kotlin-dsl`
}
repositories {
jcenter()
}
また
apply {
plugin("kotlin")
}
buildscript {
repositories {
gradlePluginPortal()
}
dependencies {
classpath(kotlin("gradle-plugin", "1.3.72"))
}
}
//dependencies {
// implementation(gradleKotlinDsl())
// implementation(kotlin("stdlib", "1.3.72"))
//}
repositories {
gradlePluginPortal()
}
異なるバージョンbuildSrc
間のbuild.gradle
ファイル実行順序:
gradle-wrapper.properties:5.6.4
com.android.tools.build:gradle:3.2.0
BuildSrc:build.gradle
setting.gradle
Project:build.gradle
Moudle:build.gradle
gradle-wrapper.properties:6.5
com.android.tools.build:gradle:4.1.1
setting.gradle
BuildSrc:build.gradle
Project:build.gradle
Moudle:build.gradle
したがって、buildSrc
ディレクトリ以外のファイルの読み込み順序に注意する必要がありますbuild.gradle.kts
。Dependencies.kt
参照文書
Android 公式 Web サイト - ビルド構成を Groovy から KTS に移行する
Groovy から Kotlin へのビルド ロジックの移行
GitHub:kotlin-dsl-samples/samples/hello-android
Kotlin DSL: Android の Gradle スクリプトを簡単に
記事はここですべて説明します。他に連絡が必要な場合は、メッセージを残してください〜!〜!
著者の記事をもっと読みたい場合は、私の個人ブログと公開アカウントをチェックしてください。