Android
Kotlin

KotlinでAndroidのpublic methodをoverrideするときに気をつけること

More than 1 year has passed since last update.

TL;DR (長い3行で)

  • KotlinでonActivityResult()をoverrideして,startActivityForResult()したら,
  • FrameworkがonActivityResult()の呼び出しに失敗してCrashする.
  • Platform型(Intent! == Intent or Intent?)を意識して引数の型を変えないとダメ.

JAVA→Kotlin化でやったこと

もともとあったAndroid JAVA AppのActivityをKotlinに書き換えていたときのこと.
Runtime Permission解決のくだりで,↓ のようなKotlin CodeにしてSettingsを呼び出しています.

Activity.kt
overide fun onResume() {
    ....
    if (!Settings.canDrawOverlays(this)) {
        val intent = Intent(
                Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + PACKAGE_NAME))
        startActivityForResult(intent, REQUEST_CODE)
    }
    ....
}

Settings終了後のonActivityResult()も ↓ のようにKotlin化しました.

Activity.kt
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent) {
    ....
    if (requestCode == REQUEST_CODE) {
        if (!Settings.canDrawOverlays(this)) {
            finish()
        }
    }
    ....
}

起こる問題

実際に上のCodeを実行すると,
App起動→SettingsApp起動→Java Crash
になります.

Crash Logは ↓ のようなもの.

D/AndroidRuntime( 6186): Shutting down VM
E/UncaughtException( 6186):
E/UncaughtException( 6186): java.lang.RuntimeException:
        Failure delivering result ResultInfo{who=null, request=100, result=0, intent=null} to activity {package/class}:
        java.lang.IllegalArgumentException: Parameter specified as non-null is null:
        method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter intent

解決のためにやったこと

Logにかかれているとおり,non-null型にnullを入れようとしてonActivityResult()の呼び出し時に実行時Errorになっている模様.
onActivityResult()の引数の型を

override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?)

としてあげれば正しく動作するようになります.
(Kotlin側で引数を使うときはnull check等でnon-null化は必要になりますが)

まとめ

Platform型の話をKotlin勉強会で聞いていたので,そこまで戸惑わなかったですが,
初見でこのError見たらけっこうハマってたかもしれません.

Android StudioのJAVA→Kotlin Convert使えばこのへんもかしこくConvertしてくれるのかな.

---///