Supershipとは?|Supership株式会社
Supershipのビジョンやミッション等を紹介しています。
https://supership.jp/about/
こんにちは。Supershipの新規サービス開発室というところでAndroidエンジニアをしてる松下です。今回は僕が所属しているチームのAndroidアプリをJavaからKotlinに移行した話をします。
Androidアプリ開発のつらいところとして、なかなかJava本体の進化の恩恵を受けられないところがあります。JetBrainsが開発しているKotlinは後発の言語らしく、モダンな言語のいいところを取り入れていて書きやすい言語です。Androidアプリ開発においては、AndroidStudioにプラグインを入れるだけで簡単にKotlinの導入ができるので、手軽にJavaとは違った書き味でコードを書き始めることができます。
ちょうどKotlin 1.0がリリースされた時に、移行できそうならしてしまうか!という話が出てきて、チーム内で相談して以下のポイントを考慮してGoしました。スモールチームで開発していると意思決定の早さがいいですね。
特に、既存のJavaのリソースを生かしたまま部分的にKotlinの導入ができるのは、大きなポイントで、サービス開発を止めないで移行することができました。立ち上げ期でアプリ自体はそこそこ出来上がっている状態だったので、開発を止める必要があったのなら移行するという判断はできなかったでしょう。
移行作業は1日のうち30分から1時間程度を移行作業用の時間として確保して少しずつKotlinの割合を増やしていきました。結果、特に大きなトラブルもなく、サービスの開発スピードを落とさずに移行ができました。フルKotlin化達成です。
Kotlinでは型の後ろに?をつけることでNullを許容できる型かどうか区別することができます。また、参照するときのNullチェックも簡潔で以下のように書けます。
val text: String? = null
// NPEは起きずにlengthはnull(型はInt?)が返る
val length1 = text?.length
// エルビス演算子(?:)を使うと nullだった場合の値を返せる
val length2 = text?.length ?: 0
Nullable型のメリットはNullPointerExceptionが起きなくなるというよりは、Nullを意識した実装がしやすくなるというニュアンスの方が合ってるかなと思ってます。本来、Null Checkしなければいけないところがわかりやすくなるという感じですね。 ? をつけてNPEを起きなくしても本質的な対応にはならないはずです。
データの保持を目的とするクラスを作ることはよくあるかと思います。例えばユーザーのIDと名前を持っているクラスをKotlinで書くと、dataアノテーションを使ってこのようにシンプルに書けます。
data class User(val id: String, val name: String)
Javaで同様のユーザーを表現するクラスをきちんと書こうとすると、equalsやhashcode、toStringを実装する必要がありますが、Kotlinではこれだけで済みます。Kotlinはビルド時にこれらのメソッドを生やしてくれるので、上記のクラスのインスタンスは値の比較が正しく行えます。
List操作はどの言語を触ってもあるかと思います。Javaの場合はJava8からStream APIが実装されたものの、Android開発においてはバックポートするためのライブラリを入れないと使えません。
Kotlinの場合はmapやfilter、fold、 reduceといった関数が標準で用意されていますので、for文で回さずに簡潔に書くことができます。
KotlinでDaggerやDataBindingなど、ビルド時にコード解析してクラスファイルを生成する系のライブラリを使うときは、annotationProcessor ではなく kapt を指定します。
kapt自体は素晴らしいツールですが不安定な時があります。この記事を書いている今まさに困っているのですが、kaptとDaggerに起因するissueを踏んでいてKotlinのバージョンを最新(1.0.6)にあげられていません。
JetBrainsの該当のissueを覗くと1.0.7にて対応と書いてあり、対応は早い印象ですので、ユーザーとしてはissueを見つけたら積極的に報告して、Kotlinの開発に寄与していくというスタンスが良いと思います。
Javaにない予約語が定義されているので、Javaでは特に問題なく使えていたライブラリが、Kotlinでは予約語とぶつかる可能性があります。例えばKotlinだとwhen やis が予約語なので、テストで Mockito を使おうとすると、Mockito に生えているwhenとぶつかります。その場合はこんな感じで囲む必要があってちょっとめんどくさいです。
Mockito.`when`(user.getName()).thenReturn("name")
これはKotlinに限った話ではないですが、Androidの開発におけるメイン言語はJavaに変わりは無いので、例えばJack & Jillといったような新しいツール類はKotlinではすぐに使えなかったりします。
いかがだったでしょうか。Kotlinは現在1.0.6がリリースされ、安定して開発が進められています。今あるアプリを移行するというのはなかなか難しいかもしれませんが、これから新しく始めるAndroidの開発については選択肢の一つになりえるのではないでしょうか。
さいごに、弊社では行動指針として5つのバリューを掲げており、そのひとつに Super challenge があります。
今回のKotlinの導入のように迷ったら積極的にチャレンジできるカルチャーがありますので、興味を持たれた方は話を聞きに来てみてください。