この記事はAndroid Advent Calendar 2022のカレンダー2の12月25日の記事となります。
私はAndroidアプリのビルド処理の際にassetsファイルなどをapiから自動で取得したりといった処理をbuild.gradle(.kts)にtasksとして直接書いていました。
ただこの方法だと普段KotlinやJavaでやっているようなpackageやファイルの分割などが難しくてコードの整理ができず、ぐちゃぐちゃな状態になっていました。
これを普段KotlinやJavaで書いているようにできると便利だなと思い調べてみました。
いろいろ応用が効きそうで便利なため使ってみてください。
前準備(任意)
-
settings.gradle
,projectroot/build.gradle
,app/build.gradle
をそれぞれkts化(kts化することを何と呼べばいいかわからない)しておく- 必須ではないですが本記事ではkts化前提で記述しています.
buildSrcの追加
- project rootに
buildSrc
ディレクトリを追加 -
buildSrc/build.gradle.kts
を追加 - gradle sync
- これでbuildSrcディレクトリが認識されるはず
- build.gradle.kts に以下を記述
build.gradle.kts
plugins { kotlin("jvm") version "1.6.10" //おそらくアプリ全体でばーじょんを合わせないとだめ } buildscript { repositories { mavenCentral() } dependencies { classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10") } } repositories { mavenCentral() } dependencies { implementation(gradleApi()) implementation(localGroovy()) //taskで必要なものを任意で追加. //通信処理を書きたい場合はktorを追加するなど }
処理を記述するKotlinファイルを追加
-
buildSrc/src
ディレクトリを追加 - AndroidStudio上から
-
src
を右クリック - [New] -> [Directory] -> [main/kotlin]
-
-
main/kotlin
に任意のpackageを追加 (本記事ではjp.pmcoffee.tasks
) - 任意でpackageを分ける. 今回は hoge, fugaを追加
jp.pmcoffee.tasks.hoge
jp.pmcoffee.tasks.fuga
- それぞれのpackageにclassを追加. 今回はそれぞれ
HogeTask
,FugaTask
- HogeTaskに以下のように記述(FugaTaskも同様に)
package jp.pmcoffee.tasks.hoge import org.gradle.api.DefaultTask import org.gradle.api.tasks.TaskAction abstract class HogeTask: DefaultTask() { @TaskAction fun runTask() { println("run HogeTask") } }
- DefaultTaskを継承することとtaskとして実行したい関数に@TaskActionアノテーションをつけることが大事.
gradle taskとして登録
-
project_root/build.gradle.kts
に以下を追記build.gradle.ktstasks.register("runHogeTask", jp.pmcoffee.tasks.hoge.HogeTask::class) tasks.register("runHogeTask", jp.pmcoffee.tasks.fuga.FugaTask::class)
-
gradle sync
これで gradle taskにrunHogeTask
, runFugaTask
が登録される
登録したgradle taskを実行
ProjectRoot Dirと引数
ProjectRoot Dirの取得
何かと必要になるProjectRoot Dirの取得方法です。
-
project.rootDir.absolutePath
で ProjectRoot Dirを取得できるpackage jp.pmcoffee.tasks.fuga import org.gradle.api.DefaultTask import org.gradle.api.tasks.TaskAction abstract class FugaTask: DefaultTask() { private val projectRootDir = project.rootDir.absolutePath @TaskAction fun runTask() { println("run FugaTask. projectRootDir = $projectRootDir") } }
引数
build.gradle.ktsから引数を受け取る
@Inputアノテーションを使う
abstract class FugaTask: DefaultTask() {
private val projectRootDir = project.rootDir.absolutePath
@Input
var arg1: String = ""
@TaskAction
fun runTask() {
println("run FugaTask. projectRootDir: $projectRootDir")
println("arg1: $arg1")
}
}
tasks.register("runFugaTask", jp.pmcoffee.tasks.fuga.FugaTask::class){
arg1 = "from build.gradle.kts"
}
実行設定で引数を指定する
- アクセストークンなどユーザー毎に固有の値が必要な場合、build.gradleに引数を書くのはセキュリティ上良くないので, そういう場合はこちらの方法を使うといいかと思います.
abstract class FugaTask: DefaultTask() {
private val projectRootDir = project.rootDir.absolutePath
private val arg2Name = "arg2"
private val arg2: String = if(project.hasProperty(arg2Name)) project.property(arg2Name) as String else ""
@TaskAction
fun runTask() {
println("run FugaTask. projectRootDir: $projectRootDir")
println("arg2: $arg2")
}
}
まとめ
- gradle taskを普段androidアプリ開発をしている時と同じようにpackageおよびファイルを分けて書くことができた
- 引数を指定して任意で実行できる
感想
久々にアドベントカレンダー書きました。
当日(今日)の朝に書いてなかったことを思い出して、だいぶ焦ったり。
突貫で書いたのでわかりにくい部分などあるかもしれませんので、その際は質問などしてもらえればと思います。
追記
タイトルが誤字ってるのを指摘してもらいました。ありがとうございます。
自分だとなかなか気づかないもんですね。
(間違いがショボすぎて恥ずかしいわぁ)
- Koltin
+ Kotlin