Edited at

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してくれるのかな.

---///