Java
Android
Kotlin

Androidアプリ(Java)をKotlinに全変換


概要

会社のアプリを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という周辺検索アプリ。

qiita.gif

https://play.google.com/store/apps/details?id=com.hikarusato.placesearch



対応工数

2日


  • Kotlinコードに書き換えて、大体の機能が動くレベルになるまで



やり方


  1. Android StudioにKotlinが入ってなかったら、pluginインストール。いろいろな記事にやり方があります。

    http://blog.ch3cooh.jp/entry/20160217/1455676200

  2. 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

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]。

スクリーンショット 2017-02-04 23.51.16.png

これで、全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変換精度もバージョンアップを重ねれば上がってくるはず。