Java経験者がKotlinで実装したアプリをGoogle Playでリリースするまでに得た気づき

# 概要
日頃、Javaに触れている筆者が、KotlinでAndroidアプリを作成し、Google Playに公開した一連の中で得た気づきを共有できたらと考えています...

# 前提・背景
Java：ある程度読み書きできます...Androidアプリは過去に個人レベルでJavaにて実装経験がありました。
Kotlin：興味をよせていましたが、KotlinでのAndroidアプリ実装経験はありませんでした。

# デバッグに使うAndroid仮想マシンのアイコンランチャに、開発中アプリのアイコンが2つ存在する...
開発中、デバッグ環境としてAndroid Studioに標準搭載のAndroid仮想マシンを使っていました。デバッグや実行をすると、当該アプリがインストールされランチャーに開発アプリのアイコンが追加されます。ところが、まったく同じアイコン・名前のアプリがランチャーに2つ表示されていました...

## 原因・解決
AndroidManifest.xmlにて、以下の2つの記述が、複数のActivityの各`<intent-filter></intent-filter>`内に重複記述されていることが原因でした。
```xml:AndroidManifest.xml
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
```
この2つの記述は、通常アプリ起動時 最初に表示するActivity(アプリ内で1つ)に付与するものでした。
初回同意画面と、アプリ本体のそれぞれでActivityを分けていて、AndroidManifest.xmlにて重複記述しており、修正したところ解消しました！

# staticメソッドは、Kotlinでどう記述するのだろうか...
Kotlinでは、staticメンバがないとのWeb情報で、詰まりました。

## 解決
Kotlinでは、コンパニオンオブジェクトという機構を用いて同等のことが実現でき、解決しました！
```
class クラス名 {
    companion object コンパニオンオブジェクト名 {
        fun メソッド名()
    }
}
```

## Kotlinでのシングルトン実装。getInstanceメソッドを定義して...staticなフィールドを定義できない事に気が付く
同じく、staticメンバがないとのWeb情報で、詰まりました。

## 解決
Kotlinでは、クラス定義時にobjectキーワードを付与すると、シングルトンになると分かり、解決しました！
```
object クラス名 {
    val 変数

    fun メソッド{
    }
}
```

# key-value形式でアプリ設定保存したいものの、SharedPreferencesでの実装は古い模様...
Javaでアプリ実装した際は、SharedPreferencesを用いていました。

## 解決
現行は、Preference DataStoreを用いるとの情報があり、Android Developerの公式サイトを参考に、実装しました。Preferencesは、java.util.Preferencesではなく、androidx.datastore.preferences.core.Preferencesが使われていることを確認し、コンパイルエラーも解決しました！


# Kotlinの独自の用語がわからない...記号なので検索しても見つけられない...
## 「`変数.let{}`」と「`?:`」（スコープ関数、エルビス演算子）
```
変数.let {処理} ?: 変数がnullの場合
```
`.let{}` をスコープ関数と呼ぶと知りました。 `?:`はエルビス演算子と呼ぶと知りました。
上記の意味は、変数が`null`以外の場合、処理が行われ、変数が`null`だった場合はエルビス演算子`?:`の右辺(変数が`null`の場合) が実行されます。

スコープ関数には、letの他にapply、run、also、withがある模様。

## 「`変数?`」と「`型?`」（安全呼び出し、Nullable記号）
`変数?.let{}`というように変数の後ろに記述された`?`は、「安全呼び出し」と呼ぶと知りました。これは、`null`ではない場合のみ`.let{}`などの処理を行い、`null`の場合は処理を行わず`null`を返すという挙動となります。

`?`の付く位置が、`型?`というように変数の「型」の後ろにつく場合は、「Nullable記号」と呼ぶそうです。これは、変数がnullになりえるということを意味します。Nullable記号をつけない場合、Kotlinでは変数にnull代入できないと認識しました。

# it と let
itはどこから来たのか...

## 解決
ラムダ式にて、`x -> x + 1`という処理があった時、`it + 1`と書き換えられると分かりました。つまり、`it`は、`.let{}`が定義された「変数自身」を表していると理解しました。
```
リスト型の変数?.let{
    for(item in it){
        要素に対する処理(item)
    }
}
```
上記では、MutableList等のリスト型の変数の要素を取り出し、要素に対する処理を行うという意味になります。
`変数?.let{}`となっているので、`null`の場合は実行されないことも併せて認識できました。

# コルーチンという概念が分からない...
並列処理を担うイメージはつきました。

## 解決
コルーチンとは、軽量スレッドのようなものと認識しました。他の処理をブロックせずに、並列で処理を行うことを可能にする機構です。
`GlobalScope.launch{処理}`というように記述します。
`launch{処理}.join()`とすることで、処理が終了するまで待ち合わせることができます！

# (Javaではないが)C#でいう asyncメソッドと awaitで非同期で戻り値を得たいが、コルーチンを使えばできるのだろうか...
並行してC#でもアプリを実装していたため生じた発想でした。

## 解決
```
suspend fun メソッド {
    処理
}
```
メソッド定義時に、`suspend`を付与することで、Suspend関数として定義でき、コルーチン内で処理を中断(待機)可能なメソッドとして定義できると知りました。
Suspend関数を呼び出すことができるのは、コルーチンの中からのみであると認識しました。
Suspend関数の処理が終わるまでは呼び出し元のコルーチン内の処理が待機すると理解しました。
C#でのasyncメソッドと呼び出し時のawaitと同等のことができると分かりました！

# `suspend fun`にて、コルーチンwithContextの結果を戻り値にしたいが...
コルーチンの中のブロックでただ`return`と書くだけではダメな模様...

## 解決
withContextブロックの中では、`return@withContext`と記述することで、withContextコルーチンとしての戻り値となると理解しました。あとは、`return withContext...`として、さらに`suspend fun メソッド`の戻り値として返すことで解決しました！
```
suspend fun メソッド {
    return withContext(Dispatchers.IO){
        変数に対する何らかの処理
        return@withContext 変数
    }
}
```

# `GlobalScope.launch{}`の処理内で、途中で処理を終えたいが...
コルーチンの中のブロックでただ`return`と書くだけではダメな模様...

## 解決
`return@ラムダ式名`　とすることで、指定したラムダ式(ブロック部分)から抜け出すという意味であることを理解し、解決しました！
```
GlobalScope.launch{
    処理
    途中で終えたいとき
    return@launch
    処理
}
```
# アプリ開発以外の要対応事項に意外と工数がかかる
Google Playへのアプリ申請に際して、アプリ開発以外にも以下の作業が必要となりました。

## 開発者アカウントの取得
アカウント取得は有料となります。過去にAndroidアプリをJavaで実装しリリースしていたためすでに開発者アカウントを保持していたため、影響はなかったのですが、2023年11月ごろ、個人用の開発者アカウントを新規取得した場合のアプリ公開要件の変更が話題となっていました...アプリ公開前にアプリテストの要件が追加されたそうです。


## リリース申請用にアップロードするBundleへの書き出し
Android Studioにて行います。Bundle作成に当たり、アップロード鍵とキーストア作成が必要で、使用するパスワードを考えておく必要があります。Android Developerの公式サイトを参考にしました。
この時に作ったアップロード鍵とキーストアは、今後アプリの更新をリリースしていく際に必要となるため、取り扱いに注意する必要があると認識しました。

## プライバシーポリシー、利用規約の作成
初回同意画面を用意したことと、プライバシーポリシーは申請時に必要となるため、作成しました。

## リリース申請に使う画像や文章、情報の用意
アプリ名、アプリの説明、スクリーンショット作成、アプリロゴの作成が必要です。アップロード可能な画像のピクセル数が厳密だったので、別途画像編集ソフトを用いました。

## Google Playへのリリース申請
公開国・地域の設定、各種アンケートへの回答、データセーフティの申告など、リリース申請に必要な情報を入力していきます。
データセーフティでは、アプリで扱うデータの種別や扱われ方を細かく認識し申告していく必要がありました...

# Google Playの審査期間が想定より日数が必要だった...
初回リリースだったためか、申請してからGoogle Playに表示されるまでに今回の場合5日程度かかりました。
状況により所要日数は変化するかもしれないので、余裕をもってリリース申請したほうが良いと認識しました。

# むすび
Javaとの違いを認識しながら今後もKotlinに触れていきたいと考えています...
最後までお読みくださり、ありがとうございました！