新しく作ったテレビ実況AndroidアプリでKotlinを使ったのでいいなと思ったこと3点を書きます。
1.findViewById
や追加の記述なしにViewのインスタンスを使える。
import kotlinx.android.synthetic.activity_top.*
class TopActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_top)
setSupportActionBar(myToolbar)
supportActionBar.title = "MyTitle"
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/myToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:theme="@style/ToolbarTheme"/>
</FrameLayout>
これはKotlin AndroidExtensionsの機能です。
TopActivity.kotlin
でmyToolbar
というToolbar
型のインスタンスが何の定義もなしに使われています。
上部のimport文の通り、import kotlinx.android.synthetic.layout_file_name.*
を書くとlayoutファイル内に記述したビューのインスタンスが、そのid名でプロパティとして生成されます。これでfindViewById
を駆逐できます。
今までView
のidはスネークケースで書いていましたが、Kotlin側ではキャメルケースで使いたいのでキャメルケースに統一して記述することにしてました。
2.SAMや関数リテラルで可読性アップ
Kotlinでリスナーやコールバックをスッキリと書く【関数リテラルとSAM変換】
が詳しいですがとにかく行数が減ります。
よくあるクリック処理の実装はJavaでは
button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v){
Log.v(TAG,"click!")
}
}
ですが、kotlinでは次のように1行でかけます。
button.setOnClickListener { v -> Log.v(TAG, "click!") }
例えばView.OnClickListener
インターフェースはOnClick(View v)
のメソッドしか持ちませんが、このようにメソッドが一つのものをSAMインターフェース(Single Abstract Method)と呼びます。関数リテラルを然るべきメソッドに渡すとSAM変換という機能によりSAMインターフェースを実装したクラスのインスタンスに変換されるので上記のような書き方ができるそうです。
特にRxと相性がよく、Javaで
Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(final Subscriber<? super String subscriber) {
subscriber.onNext("A");
}
}).doOnCompleted(new Action0() {
@Override
public void call() {
Log.v(TAG, "onCompleted");
}
}).doOnError(new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
Log.e(TAG, "onError");
}
}).subscribe(new Action1<String>() {
@Override
public void call(String result) {
Log.v(TAG, result);
}
})
と書くのはRxKotlinも使って、
observable<String> { subscriber ->
subscriber.onNext("A")
}.doOnCompleted { Log.v(TAG,"onCompleted") }
.doOnError { error -> Log.e(TAG,"onError") }
.subscribe { result -> Log.v(TAG,result)}
という感じで書けます。
「AndroidStudioでは強い補完に頼りながらばちばちコード書けるし長い記述もそんなに苦ではないかな。可読性を高めるのには名前付け、カプセル化、共通化などのプログラミング力が重要で、こういった部分を省略して行数が減ることは本質でもないし大したことではないのでは」と少し思ってましたが、スッキリするだけで想像以上にコードが読みやすく、楽しくなることがわかりました。
3.Null安全
var c = "Kotlin!" //非NULL型(non-null type)
var d : String? = "Kotlin!" //NULL許容型(nullable type)
c = null // コンパイルエラー
d = null // OK
val a : String? = "hoge"
println(a?.size) // 4
val b : String? = null
println(b.size) // コンパイルエラー
println(b?.size) // null
println(b?.size == null) // true
というように、慣れてないとすぐに赤線コンパイルエラーがでるのでNullの可能性を考えながら安全なコードが書けます。
他
タイトルに3つと書きましたが、REPLで簡単に記法の確認ができることや、例えば1,2,3が格納されたArrayList<Int>
のインスタンスを生成するarrayListOf(1,2,3)
のような便利builtin関数があることや、fun next(n : Int) = n + 1
のような1行の関数が書けることなど他にも色々といいことがあると思います。
Kotlinはバージョンが上がって機能やdeprecatedが増えたりするのが割と多いのでリリースはチェックしておく必要がありそうです。