Android
Kotlin
AndroidStudio

KotlinなAndroidプロジェクトがBreakpointで止められない問題

Kotlin な Android プロジェクトで Breakpoint が止まらない状況

Kotlin な Android プロジェクトを大幅にリファクタリングしていたところ、いつのまにか Breakpoint で停止することができなくなっていました。

アプリがデバッグモードにならない場合は設定ミスや buildTypes の設定間違いなどはよくありますが、今回は Logcat で以下の表示が出ているため、デバッグモードで起動しており Debugger アタッチまでできているはずです。

12-01 13:59:19.447 19095-19101/net.irgaly.myapplication I/art: Debugger is active
12-01 13:59:19.633 19095-19095/net.irgaly.myapplication I/System.out: Debugger has connected
12-01 13:59:19.633 19095-19095/net.irgaly.myapplication I/System.out: waiting for debugger to settle...
12-01 13:59:19.834 19095-19095/net.irgaly.myapplication I/System.out: waiting for debugger to settle...
12-01 13:59:20.035 19095-19095/net.irgaly.myapplication I/System.out: waiting for debugger to settle...
12-01 13:59:20.235 19095-19095/net.irgaly.myapplication I/System.out: waiting for debugger to settle...
12-01 13:59:20.436 19095-19095/net.irgaly.myapplication I/System.out: waiting for debugger to settle...
12-01 13:59:20.636 19095-19095/net.irgaly.myapplication I/System.out: waiting for debugger to settle...
12-01 13:59:20.837 19095-19095/net.irgaly.myapplication I/System.out: waiting for debugger to settle...
12-01 13:59:21.037 19095-19095/net.irgaly.myapplication I/System.out: debugger has settled (1390)

プロジェクトの状態

Android Studio 3.0.1 で、Android Kotlinプロジェクトを新規で作成し、以下の状態にすると再現します。

.kt ファイルのソースコードディレクトリは新規作成時点では src/main/java/**/*.kt と配置されているが、これを src/main/kotlin/**/*.kt へと変更しています。
build.gradle の内容は新規作成からそのままです。

image.png

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "net.irgaly.myapplication"
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

このとき、デバッグ実行すると Breakpoint が以下の表示となり、実行を停止することができない状態になります。

Breakpoint does not belong to any class

image.png

解決方法

build.gradle に sourceSets 設定を追加すると Breakpoint が使えるようになります。

android {
  ...
  sourceSets {
    main.java.srcDirs += 'src/main/kotlin'
  }
}

sourceSets 指定がなくてもアプリはビルドして実行できてしまううえに、Logcat にも原因を特定できそうなエラー表示もないため、ハマると気づきにくいトラブルです。sourceSets のリファレンスを見ても Breakpoint との関係は読み取れませんでしたが、実行時にデバッグアタッチ用ソースコードの参照先としているようです。

src/main/kotlin も標準で参照先に入れてくれればこの設定もいらなくなるのに...