[Kotlin][Android] KotlinでAndroidアプリケーション [独特な書き方]

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。小室です。 札幌は今の時期、とても心地よい気候ですよー。皆様是非札幌へおいでください。

IMG_20150705_125936

KotlinでAndroidアプリを書く時に諸々ハマったので、メモしておきます。まだまだ発展途上の言語なので、とんでもない勢いで変化してます。 *1

KotlinでAndroidアプリケーションをもくもく書くのは大変楽しいのですが、全く違う書き方するものもあるので「さてどうやったら良いんだろう?」と悩む箇所も結構多く。

Kotlinで書く

私の今現在の環境は以下の通りです。

  • OS: Mac OSX 10.10.4
  • IDE: Android Studio 1.2.2
  • Kotlin: 0.12.613

コンストラクタの宣言方法

基本となるコンストラクタの書き方です。

public class Music(title:String) {
    val musicTitle = title
}

セカンダリコンストラクタは以下のように書いていきます。

public class Music(title:String) {
	constructor(title: String, price: Int) {
	}
}

セカンダリコンストラクタの中でプライマリコンストラクタを呼ぶ場合はこんな感じ。

public class Music(title:String) {
	val musicTitle = title
	
	constructor(title: String, price: Int): this(title) {
	}
}

継承の記述方法

継承自体は問題ないのですが、 super の記述が厄介です。 Javaと同じような感じで super() という継承した親クラスのコンストラクタを呼ぶことができません。

public class MainActivity: Activity() {
}

これでJavaで記述した以下のコードと同等になります。

public class MainActivity extends Activity {
	public MainActivity() {
		super();
	}
}

他の書き方としてこれも許容されてるようです。ただし、わざわざ constructor を書かねばならないため少々冗長な感じです。

public class MainActivity: Activity {
	constructor(): super() {
		// initialize
	}
}

プライマリコンストラクタで引数を取れるようにした書き方だと、こんな記述になります。 ArrayAdapter<String> を親クラスとして MyAdapter を定義します。

class MyAdapter(context: Context, items:Array<String>, tag: String): ArrayAdapter<String>(context, 0, items) {
	val tagName = tag
}

このあたりは慣れるまで結構時間がかかりました。慣れてしまうと、クラス内に定義する変数をほとんど val で記述できるので、var をガツガツ駆逐できるのでとても良いです。

匿名クラスのオブジェクト化

これは、よく OnClickListener などを記載する際によく利用します。

button.setOnClickListener(object:View.OnClickListener {
    override fun onClick(v: View) {
        Log.d(TAG, "ID"  + v.getId())
    }
})

インターフェースなどをオブジェクト化して利用する場合は、 object:Interface{ } と記述します。

ちなみにこのメソッドは、とてもJavaらしいコードです。もっとKotlinらしく変えるべきでしょう。 *2

button.setOnClickListener { v -> Log.d(TAG, "ID"  + v.getId()) }

staticメソッド、static定数の書き方

これはなかなか難問で結構Google先生のお世話になりました。 companion を利用します。

public class MainActivity: Activity() {
	companion object {
        val SUCCESS_MESSAGE = "success"
        fun getUuid() = UUID.randomUUID().toString()
    }
}

これで以下のようにアクセスできます。

Log.d(TAG, MainActivity.SUCCESS_MESSAGE)
Log.d(TAG, MainActivity.getUuid())

多重継承によるsuperの記述

これはコンパイラが教えてくれるので直すのは結構簡単です。 Activity クラスを継承し、 View.OnClickLisetner インタフェースも継承しています。

public class MainActivity: Activity(), View.OnClickListener {
    override fun onClick(v: View) {
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super<Activity>.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

onCreate() にある super<Activity> とどちらの super かを明確に指定する必要があります。

Class.thisの記述

これを解決するのに3時間くらい悩んでました。

Toast.makeText(this@MainActivity, "Tap Now", Toast.LENGTH_SHORT).show()

この記述方法は斜め上すぎて当初全く気づきませんでした・・・。

Class.classの記述

これもまたAndroidアプリの開発ではよく出てくるコードでしょう。

val intent = Intent(this@MainActivity, javaClass<AnotherActivity>())

javaClass<Class名>() と記述します。

ほんとに困ったときには

Android Studio(or Intelli j)のKotlinプラグインをインストールすると現れる Convert Java File to Kotlin File を使いましょう!

スクリーンショット_2015-07-07_23_32_06

たまにJavaで記述したはずの処理が一部消えたりするらしいので、注意しながら使いましょう。

まとめ

Kotlin特有の書き方などを中心に紹介しました。なかなかこの辺りはうまく頭を切り替えていかないと、いつも通りJavaの感覚で記述してしまうと気づくとコンパイラが真っ赤になって怒っている、などということもあるので、うまく切り替えていきたいものです。

一度慣れてしまうとAndroid Javaに戻れないほどの魅力があります。書いてて楽しい言語というのは、それだけでコーディングに対してのモチベーションが上がります。

個人的には相性が良いと言われているRxAndroidとKotlinを組み合わせて試してみたいところです。

参照

脚注

  1. array()がdeprecatedになってarrayOf()になってるのに今日気づきました。
  2. きっともっとKotlinらしく出来るはず。