Javaで書いていたAndroidプロジェクトをKotlinに変換してみる

# 背景
昔、JavaでAndroidプロジェクトを書いていたものがある。その当時からAndroidバージョンが上がった事に伴い、古いプロジェクトを再度読み込み何とか新しいバージョンに対応する事が出来た。
そんな中、最近ではKotlinがAndroid開発の標準言語として普及しているという事を知る。
次に何か作る時にはKotlinかな、と思っていた所に、簡単にjavaからKotlinに変換出来るという話を聞く。という事で、今後の為にも今のうちにKotlinに変換してみる。
ついでに今までしていなかったGithubでの管理も始めてみる。

# 環境
Android studio 3.5.3 (後で3.6.3に上げた)

# 前準備

## Githubにjava状態でのプロジェクトを保持
何かあった時の為に元に戻せるようにはしておきたい。これを機にGithubも始める。
[\[Android Studio\] GitHub と連携してみる](https://dev.classmethod.jp/articles/android-studio-git-integration/)を参考にする。

 - メニューから「VCS」>「Import into Version Control」>「Share project on GitHub」を選択
 - ログイン画面が表示されるのでユーザ名・パスワードを入れてログイン
 - プロジェクト名(リポジトリ名)が求められるので入力。privateリポジトリにする事も可能らしい。remoteの指定は「origin（デフォルト）」のまま。
 - initial commit で登録するファイルを選択するダイアログが表示される。
 - 生成物である「build」「release」フォルダ配下は除外。「gradle\wrapper」も生成物っぽいので除外。「keystore」ファイルも除外。
 - OKすると、リモートにリポジトリが生成されている。masterブランチに先ほど指定したファイルが登録されている状態。

## Kotlinに変更する用のブランチ作成
 - 「VCS」 > 「Git」>「Branches」
 - 「New Branch」で、develop ブランチ作成（同時にチェックアウト）
 - 「VCS」 > 「Git」>「Branches」で、developにタグマーク（現branch）がある事確認
 - 「VCS」 > 「Git」>「Push」でdevelopブランチをリモートにPush
 - Github側で、developブランチをデフォルトブランチに変更
 - 「New Branch」で、kotlin-base ブランチ作成（同時にチェックアウト）
 - 「VCS」 > 「Git」>「Push」でkotlin-baseブランチをリモートにPush

# 変換実行

## Kotlinプラグインインストール
「File」>「Settings」>「Plugin（左メニュー）」でInstalledでKotlinが既に含まれていたのでそのまま。

## 変換実行
 - Androidプロジェクトナビゲーションで、app->javaフォルダを選択
 - メインメニュー[Code]->[Convert Java File to Kotlin File]。
 - (javaフォルダで右クリック >「Convert Java File to Kotlin File」でも)

## いくつかの変更
変換実行すると以下の様なダイアログが出てきた。何か所か修正が必要らしい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530376/67ef8e38-0151-df65-20c3-9945fec7bc74.png)

Kotlinとは関係ないものも含まれると思うが、羅列してみる。

#### Context.MODE_PRIVATE が参照エラー
該当箇所に、カーソル併せて Alt + Enter。以下Import文が追加されて解消。
import android.content.Context

#### 変数がアンダースコア区切りで警告
キャメルケースに変更。

#### nullable変数を関数に使ってる所でエラー
変数宣言では!!がついているが、関数に渡す部分では!!がついていない。!!をつけて対応。
多分コンバーターがまだ対応していない部分だと思う。

#### プロパティのセットは直接指定が標準らしい。
例：Labelのtextを、setTextで行ってる。エラーではないが、警告出たので修正。

```kotlin:修正前
lblQ!!.setText(formula)
```
```kotlin:修正後
lblQ!!.text = formula
```

# 実行確認

## エミュレーターへのインストールでエラー
エミュレータで実行しようとしたら失敗。取り急ぎコンパイルまでは出来たと思う。
Kotlin変換は関係ないと思うけど一応。

```console:
04/26 14:50:16: Launching 'app' on Nexus One API 22.
Installation did not succeed.
The application could not be installed: INSTALL_PARSE_FAILED_NO_CERTIFICATES
APK signature verification failed.
Retry
```
これはエミュレータをAPI29のものにしたら解消。
File > Project Structure > Modules のMin SDK Versionが、28以上だった。はい、Kotlinとは関係無い部分。

## 自家製ダイアログ開く処理でエラー
findViewById でnullが返ってきていた。昔のAndroidでは全体を探していたと思うが、今は親のLayoutをちゃんと指定しなければいけないらしい。
[findViewByIdでnullが返る](http://google-android-it.blogspot.com/2011/07/findviewbyidnull.html)
を参考に修正。これもKotlin関係無い部分。さらによく動作確認してみたら、そもそも今までの指定もおかしかった疑惑あり（findViewById使わなくてもよかった）。何かチェックが厳密になったのかな？

```kotlin:修正前
val inflater = LayoutInflater.from(this)
val layout = inflater.inflate(R.layout.resultinfo_dlg, findViewById<View>(R.id.layout_resultdlg) as ViewGroup)
```

```kotlin:修正後
val factory: LayoutInflater = LayoutInflater.from(this)
val layout = factory.inflate(R.layout.resultinfo_dlg, null)
```

# gitへPush

 - VCS > Commit
 - VCS > Git > Push

# 感想

### Kotlin関係部分
今回はシンプルなプロジェクトで試したという事もあったとは思うが、Kotlinに関しては、命名規則などKotlinのルールに乗っていなかった部分の修正のみで完了した。簡単だという噂通りだった。
javaよりNullに関しての制御が厳しくなったというけど、javaとの親和性が高いという噂通りにその回避策は準備されていた。そして今回のソースでは「!!」と「?」だらけとなった。一から新しいソースを作成する場合にはそこらへん気にしながら実装しようと思うが、今回はそのまま。

### その他
今回初めてGit連携を使って見たが、これも簡単に出来た。
結局自分の作り方とかが悪かった事に起因する問題ばかりだった。今回の投稿はあまり皆さんの役には立ちそうにない。逆説的にAndroidプロジェクトのjavaからKotlinへの変換は簡単だから、今のうちにやっておいた方が良いという事は言えると思う。

# 参考にさせてもらったページ

[\[Android Studio\] GitHub と連携してみる](https://dev.classmethod.jp/articles/android-studio-git-integration/)

[【Android】AndroidのJavaコードをKotlinに変換する](https://qiita.com/Nana_777/items/e05f312c69d735c8d100)

[Androidアプリ(Java)をKotlinに全変換](https://qiita.com/HIkaruSato/items/4a5a7906761b19217370)

[Kotlin コード規約（ Naming rules ）](https://qiita.com/hmiyado/items/feea2cdd196ef53b1a1a)

[findViewByIdでnullが返る](http://google-android-it.blogspot.com/2011/07/findviewbyidnull.html)