この記事は 株式会社ソニックムーブ Advent Calendar 2017 23日目の記事です。
株式会社ソニックムーブ
https://www.sonicmoov.com
島根事業所のFacebook
https://www.facebook.com/sonicmoov.shimane
はじめに
先日島根県松江市で行われた「フロントエンド勉強会 in 山陰#03」イベントに参加し、KotlinでAndroid開発について発表をさせていただきました。発表の資料も公開したので、ぜひご覧ください。Kotlin+Android
はじめてのブログの記事ですが、発表した内容をこちらも説明したいと思います。
Kotlin
KotlinはJetbrains社が開発しているオブジェクト指向プログラミング言語です。ちなみに、Android StudioがベースしているIntelliJ IDEAのIDEもJetbrains社が開発しています。
Kotlinの特徴をいくつかまとめます:
- 関数型と静的方付けの言語である
- Apache 2.0ライセンスに基づいてオープンソースのプロジェクトである(Github)
- Java仮装マシン(JVM)上で動く
- Javaとの互換性は100%
ちなみに、Kotlinを開発しているチームがロシアにいて、コトリンはロシアにある島の名前です。
履歴
今までのKotlinの大きいマイルストーンを下記にまとめます。
- 2010年:Kotlinの開発開始
- 2011年7月20日:Jetbrains社がKotlinを開発することを発表しました
- 2012年2月14日:Apache 2.0ライセンスに基づいてオープンソース化になりました
- 2016年2月15日:Kotlin v1.0リリース
- 2017年5月17日:Google I/OでAndroidアプリ開発に当たって第一級言語の一つ選定
Android世界
KotlinでAndroid開発ができることになってから、Kotlinで開発したアプリがどんどん増えていますね。
参考:Androidデベロッパー Kotlin and Android
Slack
、Reddit
など、最近の人気のアプリも入っています。
Kotlinの機能
当記事ではKotlinの入門の話をするつもりではありませんが、一応自分が気に入った機能を紹介します。
基本の関数
例として加算する関数を書きます。
fun add(x: Int, y: Int): Int {
return x + y
}
Kotlinではもし関数中に一つだけのオペレーションがあれば、括弧を外しても問題ないです。
fun add(x: Int, y: Int): Int = x + y
また、型推論があるので、結果の型が決まってるから、下記のように実装もできます。
fun add(x: Int, y: Int) = x + y
Java、Cなどと比べると、コードの量がかなり減りますね。
Nullable
Javaエンジニアがよく知っているNullPointerException
の例外を予防するため、KotlinがNull安全(Null safety)
用のNullableを提供します。
Javaの場合下記のコードで例外が発生します。
MyClass ins = null;
ins.toString();
例外が発生しないためKotlinでNullableを使えます。Nullable型はnull
になる可能性の変数の型です。クエスチョンマーク?
で宣言します。
var ins: MyClass? = null
ins?.toString()
毎回ins
のメソッドを参考する時に、ins?.
でnull
かどうかを確認します。
プログラムをコンパイルする時にnullのチェックをしていない場合はコンパイルエラーが発生しますので、チェックの漏れがこれでなくなります。
val a: MyClass = null //コンパイルエラー
val b: MyClass? = null
b.toString() //コンパイルエラー
when
Kotlinのwhen
はJavaやCなどのswitch
代わりのキーワードです。
fun cases(obj: Any) {
when (obj) {
1 -> println("One")
"Hello" -> println("Greeting")
is Long -> println("Long")
!is String -> println("Not a string")
else -> println("Unknown")
}
}
when
の特徴は他にもあります:
-
when
が値を戻す - 戻り値は自動でキャストされます
- 引数は必須ではありません
上記の3点を含めて、下記のように実装ができます。
val res = when {
x in 1..5 -> "X between 1 and 5"
s.contains("Hello") -> "Greeting"
else -> "Unknown"
}
拡張関数
既存のクラスを拡張したい際に、拡張関数という機能を使えます。
例としてMutableList
クラスに2つの持っているエレメントを取り替えたい時、下記のように実装ができます。
fun<T> MutableList<T>.swap(index1: Int, index2: Int) {
val tmp = this[index1]
this[index1] = this[index2]
this[index2] = tmp
}
拡張プロパティ
関数と同様に既存のクラスのプロパティの宣言も可能です。
val<T> List<T>.lastIndex: Int
get() = size - 1
Androidでどうなる?
KotlinでAndroid開発する場合、Javaの場合と比べて説明します。
シンプル
まずJavaよりシンプルに実装が出来ます。2つのパターンを説明します。
データクラス
Javaの場合モデルクラスを開発する際は、get
やset
やtoString
などの関数も含めて実装をしないといけません。
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Kotlinの場合はdata class
を使います。
data class Person(val name: String, val age: Int)
上記のコードで下記のメソッドが自動で定義されます。
- get
- set
toString
hashCode
equals
val p1 = Person("Michel", 30)
val p2 = Person("Michel", 30)
println(p1.equals(p2)) // true
ラムダ式
例として、画面のレイアウトのコンポーネントにonClick
リスナーを設定する際のコードを説明します。
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
doSomething();
}
});
上記のコードをKotlinへ単純に変換すると下記のコードになります。
view.setOnClickListener(object: OnClickListener {
override fun onClick(v: View) {
doSomething()
}
})
OnClickListener
というインターフェースが一つのメッソッドだけを定義していますので、下記のようにシンプルになります。
view.setOnClickListener({ view -> doSomething() })
view
の引数を使っていないので、下記のように実装できます。
view.setOnClickListener({ doSomething() })
setOnClickListener
の引数は一つしかないため、ラムダ式で書いても大丈夫です。
view.setOnClickListener { doSomething() }
便利なツール
自分が使ったツールを紹介します。
- Kotlin Android Extensions
- Ankoライブラリ
Kotlin Android extensions
このプラグインのおかげで、Androidエンジニアのよく知ってるfindViewById
が不要になります。
例として、TextView
のtext
の設定の実装を説明します。
<TextView
android:id="@+id/hello" />
上記のTextView
にアクセスするため、JavaでビューのfindViewById
を呼んで、キャストをしないといけません。
TextView view = (TextView) findViewById(R.id.hello);
view.setText("Hello!");
Kotlin Android Extensionsを使うことでJavaの場合よりシンプルに書くことができます。
import kotlinx.android.synthetic.<layout>.*
...
hello.text = "Hello!"
インポートを追加した上で全てのid
を持ってるレイアウトのコンポーネントにアクセスが出来ます。キャストも不要で直接TextView
の関数を呼べます。
参考:Kotlin Kotlin Android Extensions
Ankoライブラリ
KotlinでAndroid開発しますと、ネット上で検索する時にAnkoがよく出てくるライブラリの名前です。
このライブラリではいくつかの機能が提供されていますが、2つの気に入った機能を説明します。
参考:Anko Github
Anko layouts(DSL)
Anko Layoutsで直接Kotlinのコード内にレイアウトの定義ができます。
verticalLayout {
val name = editText()
button("Say Hello") {
onClick { toast("Hello, ${name.text}!") }
}
}
個人の意見ですが、レイアウト(ビュー)とアクティビティやフラグメント(コントローラー)をできるだけに別けた方がいいと思いますので、XMLでのレイアウトの方がいいと思います。ただし、場合によって便利の時もあるかと思っております。
Anko Intent
またシンプルの話になりますが、Ankoを使うとIntent
の宣言がかなりしやすくなります。
Kotlinでパラメーターを持つIntent
でActivity
をスタートするコードは下記になります。
val intent = Intent(this, SomeOtherActivity::class.java)
intent.putExtra("id", 5)
intent.setFlag(Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity(intent)
AnkoのIntentを使えば、下記のコードが出来ます。
startActivity(intentFor<SomeOtherActivity>("id" to 5).singleTop())
JavaからKotlinへ
KotlinはJavaとの互換性が100%で、プロジェクト内に両言語のファイルがあっても可能です。それでは、既存のJavaアプリをKotlinに変換することが一歩一歩でできます。
あと、Android Studioが便利なサポートも提供しています。例としてStackoverflowとかでコードをコピーして、Android Studioにペーストすると、下記のダイアログが出てきます。
Last but not least、Android StudioでJavaのファイルを開いたままでCode
メニューからConvert Java File to Kotlin File
オプションからIDEに任せて言語の変換が可能です。
気になったところ
Kotlin
条件演算子がない
なかなか条件演算子を使うことになれたら、ないとちょっと面倒だと思います。一応Kotlinで下記の実装ができます。
val res = if (i > 0) "positive" else "negative"
Swiftみたいのguard letがない
Swiftで実装しますと、guard let
がかなり便利だと思っています。Kotlinではそういうものはありませんので、ちょっと残念だと思います。
guard let obj = obj {
return
}
doSomething()
一応guard let
みたいなコードが出来ますが、あまり宜しくないと感じています。
obj?.let {
doSomething()
} ?: run {
return
}
let
はSwiftと違う
Swift言語の場合、
同一のif
条件でいくつかのlet
を使って条件を確認できます。Kotlinで同じのlet
チェックがありますが、if
に入れず、ネストでしか設定ができません。
if let a = a, let b = b {
a.doSomething()
b.doSomething()
}
同じのコードをKotlinで下記になります。
a?.let {
b?.let {
a.doSomething()
b.doSomething()
}
}
ただし、if
条件でnull
チェックをしますと、Nullableの関数を呼ぶ時またチェックは要りませんので、下記の実装が十分だと思います。
if (a != null && b != null) {
a.doSomething()
b.doSomething()
}
Android
KotlinでAndroidの開発に関しては、下記の2点を気になりました:
- Javaよりビルド時間が遅い( 参考)
- Javaよりパッケージファイルのサイズが大きい
Androidデベロッパーのオフィシャルサイトを参考しますと(参考):
The Kotlin runtime adds about 7,000 methods and ~1MB to your debug APK.
アプリにもよると思いますが、以上の点を気にする方は検討した方がいいかもしれませんね。
まとめ
AndroidでKotlinに変換すると習慣も変わらないといけませんが、IDEのフルサポートとJavaとの互換性で凄く楽です。
スムーズに変換ができますから、スムーズにKotlinを学べると思います。
あと、Swiftの経験を持ってる方におすすめしますね。SwiftからJavaよりKotlinがありだと思います。
個人ではまだ試していませんが、Android Studio 3.0からJava 8のサポートが始まります。Kotlinが苦手の方はそちらを考えてもいいかもしれません。ただし、まだJava 8のフルサポートがされていないため、まだ早いかと思います。
参考
Kotlin
のオフィシャルサイト
https://kotlinlang.org/
サンプルが沢山入っているKotlinのオンラインコンソール
https://try.kotlinlang.org
KotlinプロジェクトのGithub
https://github.com/JetBrains/kotlin
Kotlin Android Extensions
https://kotlinlang.org/docs/tutorials/android-plugin.html
AnkoプロジェクトのGithub
https://github.com/Kotlin/anko
Kotlin vs Java: Compilation speed(ブログ)
https://medium.com/keepsafe-engineering/kotlin-vs-java-compilation-speed-e6c174b39b5d
AndroidでJava 8サポート
https://developer.android.com/studio/write/java8-support.html
参考になれるおすすめするブログ
https://antonioleiva.com