##概要
会社のアプリをJava -> Kotlinに変換したいと思い、まず試しに自分のAndroidアプリ(全てJavaコード)でKotlinに全変換した。
その際に行った対応について。
自分のアプリの規模が小さかったからか、あまり手間がかからなかった。
##ターゲット
- Kotlinをなんとなく知っていて、javaで書かれたandroidアプリをkotlinに書き換えたいと思っている方。
- テストプロジェクトは対象外
##わたしのAndroid, Kotlin経験
- どちらも半年くらい。
- Androidアプリはプライベートで2015/8~10頃に初めて作ってリリースした。
- Kotlinは2016/8ごろに学んで、2016/8、2017/1頃にwebview+push通知のアプリをkotlinで書いてリリース。
##Kotlinに変換したアプリ
PLACE SEARCHという周辺検索アプリ。
##対応工数
2日
- Kotlinコードに書き換えて、大体の機能が動くレベルになるまで
##やり方
- Android StudioにKotlinが入ってなかったら、pluginインストール。いろいろな記事にやり方があります。
http://blog.ch3cooh.jp/entry/20160217/1455676200 - build.gladle 編集。
build.gradle(プロジェクトの方)
buildscript {
ext.kotlin_version = '1.0.6'//追加
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"//追加
}
}
build.gradle(Module:appの方)
apply plugin: 'kotlin-kapt'//kotlinでアノテーションを利用できるようにする場合は追加。
apply plugin: 'kotlin-android'//追加。
・
・
・
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"//追加。
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"//リフレクション(プロパティ名やクラス名取得)を利用するときは追加
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"//テストプロジェクトを利用する場合追加
testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"//テストプロジェクトを利用する場合追加
}
参考:https://kotlinlang.org/docs/reference/using-gradle.html
3.Androidプロジェクトナビゲーションで、app->javaフォルダを選択して、メインメニュー[Code]->[Convert Java File to Kotlin File]。
これで、全javaコードがKotlinコードに変換される。
#潰したコンパイルエラー
・NullableTypeオブジェクト.メソッド形式になっているところに !! または ? を追加。
※ Android studio 2.3 では[Convert Java File to Kotlin File]した時点で 〜!!.〜 になっている。
例
//AndroidStudioで java -> Kotlinに変換後
mWaitDialog = ProgressDialog(this, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)
//ここで、mWaitDialog!!.setMessage or mWaitDialog?.setMessage に変えろとエラーが出る
mWaitDialog.setMessage(resources.getString(R.string.now_updating))
- ほとんどがこのエラー(100個以上出た)。
- 適宣、オブジェクト!!.メソッド にしたり、オブジェクト?.メソッドにしたり、に変える。
数が多いので、わたしは途中からほぼオブジェクト!!.メソッド 形式に変更しました (nullチェックはjavaコードのときにしているはずという考えで)。
・内部クラス(internal class)内で、同じクラス内のprivateなEnumを認識できない。
自動変換後のkotlinコード
class A {
private enum class TYPE {
TYPE_1,
TYPE_2
}
internal class B {
var state = TYPE.TYPE_1//ここでenum TYPE を認識できないエラー
}
}
修正後
class A {
//private を外す
enum class TYPE {
TYPE_1,
TYPE_2
}
internal class B {
var state = TYPE.TYPE_1
}
}
・javaのEnum.valueOf(Enum名.class, "Enumの列挙名")が正しく変換されない
自動変換後のkotlinコード
enum class TYPE {
TYPE_1,
TYPE_2
}
・
・
・
Enum.valueOf<TYPE>(TYPE::class.java!!, "Enumの列挙名")//Enum.valueOf<TYPE>でエラー
修正後
enum class TYPE {
TYPE_1,
TYPE_2
}
・
・
・
TYPE.valueOf("Enumの列挙名")//Enum名.valueOf 形式に変更
##潰した実行時のエラー
・Null, parameter favicon at 〜.onPageStarted
修正前
override fun onPageStarted(view: WebView, url: String, favicon: Bitmap) {
修正後
//faviconは nullの可能性があるので、 ? を付ける。
override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
・java.lang.IllegalStateException: ViewUtils.createNaviTran…transit, enter, nextAnim) must not be null
修正前
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation
修正後
//Animationは nullの可能性があるので、 ? を付ける。
override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation?
##kotlin変換のメリット/デメリット(所感)
##メリット
- コード量が減る
- 学習コストは低い。
- 自分は、Objective-C -> Swift は一週間くらいなれなかったが、 java->kotlinは3日くらいで結構慣れた。
- 標準関数が充実している。特にリスト操作系は便利(filter, map, findなど)。
- AndroidStudioが警告でkotlinで効率的に書けるコードを教えてくれる
- 相互利用(Kotlinからjavaコードの利用ができるし、その逆もできるので)できるので、既存のライブラリも利用できる。
##デメリット
- 既存プロジェクトのjava -> kotlin変換の手間。
- apkサイズが少し増える。
- いくつかのブログで調べたところ、50KB〜800KB増えるとのことだった。
- 自分の場合、sdkバージョンやライブラリのアップデートも行ったので参考にならないが、2.2MB(10MB->12.2MB)増えた。
- ビルドがjavaの時より少し遅くなった気がする。
##まとめ
- Java -> Kotlinはそこまで大変ではなさそう。
- Swiftのメジャーバージョンアップの方が大変な印象。
- 今後AndroidStudioのKotlin変換精度もバージョンアップを重ねれば上がってくるはず。