Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
19
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

この記事は 株式会社ソニックムーブ Advent Calendar 2017 23日目の記事です。
株式会社ソニックムーブ
https://www.sonicmoov.com
島根事業所のFacebook
https://www.facebook.com/sonicmoov.shimane

はじめに

先日島根県松江市で行われた「フロントエンド勉強会 in 山陰#03」イベントに参加し、KotlinでAndroid開発について発表をさせていただきました。発表の資料も公開したので、ぜひご覧ください。Kotlin+Android
はじめてのブログの記事ですが、発表した内容をこちらも説明したいと思います。

IMG_0174.JPG

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で開発したアプリがどんどん増えていますね。

apps_made_with_kotlin.png
参考:Androidデベロッパー Kotlin and Android

SlackRedditなど、最近の人気のアプリも入っています。

Kotlinの機能

当記事ではKotlinの入門の話をするつもりではありませんが、一応自分が気に入った機能を紹介します。

基本の関数

例として加算する関数を書きます。

Kotlin
fun add(x: Int, y: Int): Int {
    return x + y
}

Kotlinではもし関数中に一つだけのオペレーションがあれば、括弧を外しても問題ないです。

Kotlin
fun add(x: Int, y: Int): Int = x + y

また、型推論があるので、結果の型が決まってるから、下記のように実装もできます。

Kotlin
fun add(x: Int, y: Int) = x + y

Java、Cなどと比べると、コードの量がかなり減りますね。

Nullable

Javaエンジニアがよく知っているNullPointerExceptionの例外を予防するため、KotlinがNull安全(Null safety)用のNullableを提供します。

Javaの場合下記のコードで例外が発生します。

Java
MyClass ins = null;
ins.toString();

例外が発生しないためKotlinでNullableを使えます。Nullable型はnullになる可能性の変数の型です。クエスチョンマーク?で宣言します。

Kotlin
var ins: MyClass? = null
ins?.toString()

毎回insのメソッドを参考する時に、ins?.nullかどうかを確認します。

プログラムをコンパイルする時にnullのチェックをしていない場合はコンパイルエラーが発生しますので、チェックの漏れがこれでなくなります。

Kotlin
val a: MyClass = null //コンパイルエラー
val b: MyClass? = null
b.toString() //コンパイルエラー

when

KotlinのwhenはJavaやCなどのswitch代わりのキーワードです。

Kotlin
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点を含めて、下記のように実装ができます。

Kotlin
val res = when {
    x in 1..5 -> "X between 1 and 5"
    s.contains("Hello") -> "Greeting"
    else -> "Unknown"
}

拡張関数

既存のクラスを拡張したい際に、拡張関数という機能を使えます。
例としてMutableListクラスに2つの持っているエレメントを取り替えたい時、下記のように実装ができます。

Kotlin
fun<T> MutableList<T>.swap(index1: Int, index2: Int) {
    val tmp = this[index1]
    this[index1] = this[index2]
    this[index2] = tmp
}

拡張プロパティ

関数と同様に既存のクラスのプロパティの宣言も可能です。

Kotlin
val<T> List<T>.lastIndex: Int
    get() = size - 1

Androidでどうなる?

KotlinでAndroid開発する場合、Javaの場合と比べて説明します。

シンプル

まずJavaよりシンプルに実装が出来ます。2つのパターンを説明します。

データクラス

Javaの場合モデルクラスを開発する際は、getsettoStringなどの関数も含めて実装をしないといけません。

Java
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を使います。

Kotlin
data class Person(val name: String, val age: Int)

上記のコードで下記のメソッドが自動で定義されます。

  • get
  • set
  • toString
  • hashCode
  • equals
Kotlin
val p1 = Person("Michel", 30)
val p2 = Person("Michel", 30)
println(p1.equals(p2)) // true

ラムダ式

例として、画面のレイアウトのコンポーネントにonClickリスナーを設定する際のコードを説明します。

Java
view.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        doSomething();
    }
});

上記のコードをKotlinへ単純に変換すると下記のコードになります。

Kotlin
view.setOnClickListener(object: OnClickListener {
    override fun onClick(v: View) {
        doSomething()
    }
})

OnClickListenerというインターフェースが一つのメッソッドだけを定義していますので、下記のようにシンプルになります。

Kotlin
view.setOnClickListener({ view -> doSomething() })

viewの引数を使っていないので、下記のように実装できます。

Kotlin
view.setOnClickListener({ doSomething() })

setOnClickListenerの引数は一つしかないため、ラムダ式で書いても大丈夫です。

Kotlin
view.setOnClickListener { doSomething() }

便利なツール

自分が使ったツールを紹介します。

  • Kotlin Android Extensions
  • Ankoライブラリ

Kotlin Android extensions

このプラグインのおかげで、Androidエンジニアのよく知ってるfindViewByIdが不要になります。
例として、TextViewtextの設定の実装を説明します。

activity_main.xml
<TextView
    android:id="@+id/hello" />

上記のTextViewにアクセスするため、JavaでビューのfindViewByIdを呼んで、キャストをしないといけません。

Java
TextView view = (TextView) findViewById(R.id.hello);
view.setText("Hello!");

Kotlin Android Extensionsを使うことでJavaの場合よりシンプルに書くことができます。

Kotlin
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のコード内にレイアウトの定義ができます。

Kotlin
verticalLayout {
    val name = editText()
    button("Say Hello") {
        onClick { toast("Hello, ${name.text}!") }
    }
}

個人の意見ですが、レイアウト(ビュー)とアクティビティやフラグメント(コントローラー)をできるだけに別けた方がいいと思いますので、XMLでのレイアウトの方がいいと思います。ただし、場合によって便利の時もあるかと思っております。

Anko Intent

またシンプルの話になりますが、Ankoを使うとIntentの宣言がかなりしやすくなります。
Kotlinでパラメーターを持つIntentActivityをスタートするコードは下記になります。

Kotlin
val intent = Intent(this, SomeOtherActivity::class.java)
intent.putExtra("id", 5)
intent.setFlag(Intent.FLAG_ACTIVITY_SINGLE_TOP)
startActivity(intent)

AnkoのIntentを使えば、下記のコードが出来ます。

Kotlin
startActivity(intentFor<SomeOtherActivity>("id" to 5).singleTop())

JavaからKotlinへ

KotlinはJavaとの互換性が100%で、プロジェクト内に両言語のファイルがあっても可能です。それでは、既存のJavaアプリをKotlinに変換することが一歩一歩でできます。
あと、Android Studioが便利なサポートも提供しています。例としてStackoverflowとかでコードをコピーして、Android Studioにペーストすると、下記のダイアログが出てきます。

スクリーンショット 2017-12-20 10.18.28.png

Last but not least、Android StudioでJavaのファイルを開いたままでCodeメニューからConvert Java File to Kotlin FileオプションからIDEに任せて言語の変換が可能です。

as_java_to_kotlin.png

気になったところ

Kotlin

条件演算子がない
なかなか条件演算子を使うことになれたら、ないとちょっと面倒だと思います。一応Kotlinで下記の実装ができます。

Kotlin
val res = if (i > 0) "positive" else "negative"

Swiftみたいのguard letがない
Swiftで実装しますと、guard letがかなり便利だと思っています。Kotlinではそういうものはありませんので、ちょっと残念だと思います。

Swift
guard let obj = obj {
    return
}
doSomething()

一応guard letみたいなコードが出来ますが、あまり宜しくないと感じています。

Kotlin
obj?.let {
    doSomething()
} ?: run {
    return
}

letはSwiftと違う
Swift言語の場合、
同一のif条件でいくつかのletを使って条件を確認できます。Kotlinで同じのletチェックがありますが、ifに入れず、ネストでしか設定ができません。

Swift
if let a = a, let b = b {
    a.doSomething()
    b.doSomething()
}

同じのコードをKotlinで下記になります。

Kotlin
a?.let {
    b?.let {
        a.doSomething()
        b.doSomething()
    }
}

ただし、if条件でnullチェックをしますと、Nullableの関数を呼ぶ時またチェックは要りませんので、下記の実装が十分だと思います。

Kotlin
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


Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
19
Help us understand the problem. What are the problem?