AndroidでKotlinをとりあえず試してみようと思い、既存のコードをKotlin変換して躓いたところをメモ。
随時アップデート予定。
retrolambdaで書いたコードが消える
Kotlin Plugin 0.11.91 で既存コードをKotlinに変換したらretrolambdaで書いていたlambdaの中身が消えた。
少しならまた書きなおしてもいいんだけど、それなりに大きいところもありここをまた書きなおすのはちょっと辛い。
それに、RxAndroidのsubscribeは引数なしでも問題なくコンパイルが通るので、消えた部分を全部探すのはさすがに面倒。
仕方ないので、lambdaで書いていた部分を普通の無名クラスに書き換えてから変換。
build.gradleからretrolambda消し去ってから、一度ビルドすればlambdaで書いてるところがコンパイルエラーになって見つかるから楽チン(?)
WRAP_CONTENTにアクセスできない
既存のコードをKotlinに変換したところLinearLayout.LayoutParams.WRAP_CONTENT
がエラーになった。
ViewGroup.LayoutParams.WRAP_CONTENT
に変更することで無事にアクセスできた。
継承元のフィールドにはアクセス出来ないのかな?言語仕様の理解が追いついてない…
(追記)
Twitterでコメントもらいました。言われてみれば「継承」はしていないというのも頷ける。
@ngsw_taroさん、ありがとうございました!
@chibatching できませんねー。というよりもstaticなメンバはJavaでも「継承」はしていないので、最初は戸惑いがあるかも知れませんがKotlinのアプローチは理にかなっていると思います。
— たろう (@ngsw_taro) April 5, 2015
Kotlin Extensions for Android で WebView がコンパイルエラー
e: /ANDROIDXML10.kt: (9, 40): Unresolved reference: WebView
e: /ANDROIDXML10.kt: (9, 49): Unresolved reference: WebView
e: /ANDROIDXML10.kt: (10, 32): Unresolved reference: WebView
e: /ANDROIDXML10.kt: (12, 40): Unresolved reference: WebView
e: /ANDROIDXML10.kt: (12, 49): Unresolved reference: WebView
e: /ANDROIDXML10.kt: (13, 42): Unresolved reference: WebView
e: /ANDROIDXML11.kt: (9, 36): Unresolved reference: WebView
e: /ANDROIDXML11.kt: (9, 45): Unresolved reference: WebView
e: /ANDROIDXML11.kt: (10, 32): Unresolved reference: WebView
(追記)
解決しました!使っていたバージョンが悪かったようです…
0.11.91
から0.11.91.1
にアップデートすることで解決しました!
ありがとうございました!
@chibatching 0.11.91.1にアップデートしたら直りますよ!
— Yan Zhulanow (@yanex_ru) April 5, 2015
extends と implements していたJavaクラス
Kotlinでは継承も実装もクラス名の後にカンマ区切りで書くっぽい。
そうするとJavaでextendsとimplements両方やってたクラスは継承元が2つあるように見える。
この状態でsuper
を呼び出すとエラーになる。どの継承元を指すのか明示する必要がある模様。
public class HogeView : View, Observable.OnSubscribe<Long> {
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super<View>.onSizeChanged(w, h, oldw, oldh)
...
}
Proguardで失敗する
Proguardを有効にすると盛大にWarningログを吐いて失敗する。
...
Warning: kotlin.dom.CloseableEventListener: can't find referenced class org.w3c.dom.events.EventTarget
Warning: kotlin.dom.CloseableEventListener: can't find referenced class org.w3c.dom.events.EventListener
Warning: kotlin.dom.DomPackage: can't find referenced class org.w3c.dom.events.MouseEvent
Warning: kotlin.dom.DomPackage: can't find referenced class org.w3c.dom.events.MouseEvent
Warning: kotlin.dom.DomPackage: can't find referenced class org.w3c.dom.events.Event
Warning: kotlin.dom.DomPackage: can't find referenced class org.w3c.dom.events.Event
...
とりあえずWarningなので無視することにする。
この状態でビルドしたAPKでも今のところ問題は起きていない。
# Kotlin
-dontwarn kotlin.dom.*
-dontwarn org.w3c.dom.events.*
新しい static final なフィールド参照で落ちる
Kitkatの端末でBuild.VERSION_CODES.LOLLIPOP
を参照すると、ビルドは通るのにNo such static fieldで落ちます。
調べてみたところ、Javaではstatic finalなフィードはビルド時にインライン化されるから古い端末でも新しいAPIバージョンで追加された値が使えるが、Kotlinでは現状インライン化されていない模様。
これ地味にきつい。
バージョンコードくらいならハードコーディングするのもまあ我慢できるけど、View.SYSTEM_UI_FLAG_IMMERSIVEとか後から追加されたフラグは全部対象になってしまう。
これの影響範囲調べるのが億劫で自分のアプリのKotlin移行に躊躇してしまっている…
●該当Issue
https://youtrack.jetbrains.com/issue/KT-6724
https://youtrack.jetbrains.com/issue/KT-6818