メモ2ブログ

メモtoウェブログ。旧ブログはこちら。 http://sakebook.blogspot.jp/

Gradleタスクでadbを実行してアプリを起動する

ちょいちょいターミナルからビルドしてアプリを立ち上げたりとかしたくなるときがあり、都度一発でできてなくて面倒なところがありました。

そうすればいいのかーって思ったのでメモと、ちょっと汎用的にしたものを共有。

こちら見かけたやつです

  • app/build.gradle
task startDemo(type: Exec) {
    dependsOn 'installDebug'
    def adb = new File("${System.env.ANDROID_HOME}", "platform-tools${File.separator}adb")
    commandLine adb, "shell", "am", "start", "-n", "com.google.maps.android.utils.demo/.MainActivity"
}

Execタスクで実行するコマンドは、PATHを通してないとGradleタスクとして実行できないです。

PATHを通すにはコマンドをファイルで渡してあげることで存在確認しつつ実行可能になります。

これを、Kotlinでかつ汎用的に書き直してみました。

環境は

  • Android Gradle Plugin v4.0.0
  • Gradle v6.1.1

です。

  • app/build/gradle.kts
tasks {
    val sdkDir = project.android.sdkDirectory
    val adb = file("${sdkDir.path}${File.separator}platform-tools${File.separator}adb")
    project.android.buildTypes.forEach { buildType ->
        val typeName = buildType.name.capitalize()
        create("run$typeName", Exec::class) {
            dependsOn("install$typeName")
            setCommandLine("bash", "-e", "-c", """
                $adb shell am start -n ${'$'}(adb shell pm dump ${project.android.defaultConfig.applicationId}${buildType.applicationIdSuffix} | grep -A 2 android.intent.action.MAIN | head -2 | tail -1 | awk '{print ${'$'}2}')
            """.trimIndent())
        }
    }
}

SDKのPATHは、環境変数やlocal.propertiesを使わなくてもAGPで取得できます。なので任せてしまうのがいいです。

project.android.sdkDirectory

実際の環境だと、debugとreleaseなど複数のBuildTypeがある場合がほとんどだと思います。なのでBuildTypeごとにタスクを作成しています。今回の例だと runXXX という名前で作成してます。

create("run$typeName", Exec::class)

installXXXタスクに依存させることで、アプリのビルドとインストールはできている状態にしています。

dependsOn("install$typeName")

アプリを起動させる部分ですが、起動させるにはパッケージ名プレフィックス付きのコンポーネント名を指定します。

コンポーネント名を取得するのは、AndroidManifest.xmlに定義してあるのでそこからXmlSlurperで取り出す例を見かけますが、今回はアプリをビルドしてインストールも済んでいるので、adbコマンドを使って取り出します。

adb shell pm dump ${project.android.defaultConfig.applicationId}${buildType.applicationIdSuffix} | grep -A 2 android.intent.action.MAIN | head -2 | tail -1 | awk '{print ${'$'}2}'

debugを開発版としている場合、パッケージ名を被らせないようにしていると思うのでsuffixをつけて対応させます。

取得したコンポーネント名を、再度adbに渡してアプリを起動させています。

参考

GitHub - googlemaps/android-maps-utils: Maps SDK for Android Utility Library

Multiple bash commands in single Gradle Exec task vs. multiple Gradle Exec Tasks each with a single command - Stack Overflow

AndroidのGradleでbuildTypes毎にtaskを作成する方法 - 混沌とした備忘録

Android Debug Bridge(adb)  |  Android デベロッパー  |  Android Developers

Launch application from command line. · GitHub