AndroidStudio3.0 CanaryでKotlin開発の事始め

# はじめに
ついにKotlinが正式サポートされたし、Android Studio3.0系でKotlinが正式サポートされるようになった。
既存のJavaコードをKotlinに変換して〜という手順は山ほどあるが、最初っからやる場合の手順が案外ないのと、地味にハマりポイントがあったのでメモ

*この記事は2017/5/24時点の情報を元に記載してます*

**[追記]**
2017/6/29: ビルドエラーの記載を追記, RealmのKotlin事情を追記

# 環境
Mac Sierra
Android Studio 3.0 Canary([ここ](https://developer.android.com/studio/preview/index.html?hl=ja)からDL)

# Android Studio 3.0を入手
[ここ](https://developer.android.com/studio/preview/index.html?hl=ja)からDL
正式版の2.0系とは違い?、Zipを解凍するとアプリケーションが解凍されるので「アプリケーション」ディレクトリに入れる。
(たしか2.0系はイメージがマウントされた気が...うろ覚え)

**もし2.0系が入っていても共存できるので消す必要はなし**

初回起動時に2.0系から設定を引き継ぐか聞かれるので任意に(基本はYes)

# プロジェクトを作成
「Start a new Android Studio project」でスタートは一緒。
その後出てくるウィザードに**「Include Kotlin support」が新たに追加されているのでチェックを入れる**
<img width="788" alt="スクリーンショット 2017-05-24 10.23.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/76726/4b728d04-1263-df87-6c80-4c5e400a5bc1.png">

これ以降は2.0系と同じ画面が続くので割愛。

# gradleの設定
快適にKotlin開発を行うため、いくつか設定が必要
## ビルドエラーを解消する
**~~2017/5/24現在、build.gradleの設定を書き換えないと以下のようなエラーが起きる~~→2017/6/29現在の最新のAndroid Studioでは発生しなくなっている模様**
<img width="1134" alt="スクリーンショット 2017-05-24 10.28.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/76726/ee6c5786-3930-4d50-9062-f924deb47ae9.png">

```
Error:Unable to find method 'com.android.build.gradle.internal.variant.BaseVariantData.getOutputs()Ljava/util/List;'.
```

すでにStackOverFlowで同じ問題が取り上げられている
https://stackoverflow.com/questions/44042754/android-studio-3-0-canary-1-unable-to-find-method-com-android-build-gradle-in

で、対処方法はKotlinのバージョンを書き換えること

```groovy:build.gradle(Project)
buildscript {
//    ext.kotlin_version = '1.1.2-3' 元の記載
    ext.kotlin_version = '1.1.2-4'
    repositories {
        maven { url 'https://maven.google.com' }
        jcenter()
    }
```

修正したら再ビルドでOK

## javaフォルダとkotlinフォルダを共存させる
プロジェクトを生成した直後は、「java」フォルダの中にktファイルが入っていて非常に残念な感じになってる
<img width="347" alt="スクリーンショット 2017-05-24 10.35.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/76726/a5fb43db-a7f0-3a84-3da7-81cce2b0a793.png">

なのでまずはandroidTest,main,test以下に「kotlin」というフォルダを作る
<img width="348" alt="スクリーンショット 2017-05-24 10.39.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/76726/84b756bf-372a-9f6c-82b2-a659297e428d.png">

しかしこのままでは単にディレクトリとしか認識されず、src系のフォルダとして認識させる必要がある。
それにはbuild.gradleに以下の記載を追加すればよいらしい([公式の記載](https://kotlinlang.org/docs/reference/using-gradle.html))(※)

```groovy:build.gradle(app)
android {
   //--省略--//
+    sourceSets {
+        main.java.srcDirs += 'src/main/kotlin'
+        test.java.srcDirs += 'src/test/kotlin'
+        androidTest.java.srcDirs += 'src/androidTest/kotlin'
+    }
}
```

再同期すればsrc系のディレクトリとして認識されるようになる。あとはktファイルを移動させればOK
<img width="351" alt="スクリーンショット 2017-05-24 10.46.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/76726/cb789036-beed-33f5-3d11-fbb750a0b050.png">

なお、既存のjavaフォルダの名前を「kotlin」にリネームする方法もあるが、後でやっぱりjava系のファイルを追加したい、となった時に整合性が取れなくなる？可能性があるので注意（未検証)

※公式の記載を見ると「Targeting the JVM」の場合は記載が違ってる。おそらくJenkinsとかでコマンドベースのビルドをする時に影響してくる可能性が高い(未検証)ので注意が必要。
もしその場合は以下のように記載する感じでいける？
以下の記載を追加してもAndroid Studio側は特に影響がないので、追加しておくほうが吉?

```groovy:build.gradle(app)
android {
   //--省略--//
    sourceSets {
         main.java.srcDirs += 'src/main/kotlin'
         test.java.srcDirs += 'src/test/kotlin'
         androidTest.java.srcDirs += 'src/androidTest/kotlin'
+        main.kotlin.srcDirs += 'src/main/kotlin'
+        test.kotlin.srcDirs += 'src/test/kotlin'
+        androidTest.kotlin.srcDirs += 'src/androidTest/kotlin'
    }
}
```

## dependencies系の設定
この辺は自分もよくわかってないです。。。
なんかこうしたらうまく行った、的なアレです。

アノテーションを使いたい場合?は、build.gradle(app)の最初に以下を追加

```groovy:build.gradle(app)
apply plugin: 'com.android.application'
apply plugin: 'kotlin-kapt' //追加
apply plugin: 'kotlin-android'
```

aptで追加してたライブラリはkaptで追加?

```groovy:build.gradle(app)
dependencies {
    //dagger2の例
    compile "com.google.dagger:dagger:2.10"
//    apt "com.google.dagger:dagger-compiler:2.10" //javaでの記載
    kapt "com.google.dagger:dagger-compiler:2.10"  //追加
}
```

## 個人的によく使うライブラリのKotlin事情
ここは未検証ゾーンです(のちのち確認して追記します、多分)。
現状ではネットで集めた情報を載せてます。

- **dagger2**→使えるらしい。厳密に言えばKotlin対応してるわけではない？が、使うときはAPIの呼び出しだけなのでDagger2もそのまま機能する...ぽい。
- **Rx系**→RxKotlinとして正式サポート。https://github.com/ReactiveX/RxKotlin
- **Retrofit2**→使えるらしい。Dagger2と同じく、Kotlin対応してるわけではない？が、API呼び出しだけなので問題なく使える、らしい。
- **Realm**→使えるらしい。[ここ](http://qiita.com/chibatching/items/affe9efa580116beb04d)のQiitaの記事に詳細があったのでそちらを参照。
 - 2017/6/29現在、**RealmオブジェクトをKotlinで実装し、Android Studio 3.0系(Gradle Verが4.0系)でAndroidTestを実行しようとした場合、Class Not Foundのエラーが出る、**というバグがある模様([該当Issue](https://github.com/realm/realm-java/issues/4662))。直近の回避策としてはJavaで実装するorAndroid Studio 2.0系(Gradle Ver2.0系)を使うことで回避できるらしい。ちなみに予測される原因は、Realm側(Java側)からKotlinのオブジェクトを使おうとするとそのままではJava側から使えず、アノテーションが必要になったり呼び出し方が変化することが原因ではないかなぁと思ってる。
- **ButterKnife**→KotterKnifeという名前に変わってサポートhttps://github.com/JakeWharton/kotterknife ただ更新が地味に止まってる？のとSnapShotなので注意(※)
- **Swagger**→[このIssue](https://github.com/swagger-api/swagger-codegen/issues/5071)で対応中。ただ、Kotlin側から見る分にはJavaでもKotlinでも同じなので特に問題にはならない。(Swaggerはライブラリではないが、よく使うので。。)

※KotterKnifeを使う場合、ライブラリの場所がSnapShotのため、Mavenレポジトリを新たに追加する必要がある。

```groovy:build.gradle(project)
allprojects {
    repositories {
        jcenter()
        maven { url 'https://maven.google.com' }
        mavenCentral()
+        maven {
+            url 'https://oss.sonatype.org/content/repositories/snapshots/'
+        }
    }
}
```