Androidアプリの開発からリリースするまでの全体像

# この記事について
この記事は2024年のアドベントカレンダーの記事です。
普段開発はしているけど、モバイルアプリ特にAndroidアプリはあまり知らないけど開発はしてみたいという人に向けた記事です。稚拙ですがAndroidアプリ開発の全体像を描いてみたいと思い書いています。


# Androidについて
Androidは[AOSP（Android Open Source Project）](https://source.android.com/?hl=ja)というプロジェクトで開発されています。プロジェクト名の通りオープンソースで開発されているため、実装の詳細を確認しようと思ったときはいつでもソースコードを追跡することで確認することができます。このようなことができるのは、定期的にアップデートがあり利用者もたくさんいるようなOSでは珍しいと思います。

## Androidのバージョン
Androidは2008年にバージョン1.0がリリースされ、2024年12月現在ではバージョン15までリリースされています。基本的に1年に1つバージョンが上がります。
Androidはこのバージョン以外にもコードネームとSDKバージョン（APIレベル）というものがあります。開発者はこのコードネームとSDKバージョンを使って後方互換性を管理しています。コードネームとSDKバージョンはバージョンのエイリアスのようなもので、バージョン15ではコードネームはVanilla Ice CreamでSDKバージョンは35となっています。サポートするAndroidのバージョンを指定するのもこのSDKバージョンを利用します。


# Androidアプリの開発と開発環境
Androidでアプリを開発していく場合、開発言語／フレームワークやエディタで変わってきます。ここではAndroidアプリを開発する場合の基本的な構成を見ていきます。

## 開発言語／フレームワーク
Androidでアプリを開発する場合、一般に考えられる開発言語とそのフレームワークは次の通りになります。（/の左が言語、右側がフレームワーク相当。/がなければ開発言語。）
- Java
- Kotlin
- C
- C++
- C# / Unity
- Dart / Flutter
- JS / React Native
- Rust / Tauri

Kotlinはそれまで使われていたJavaを置き換える形で使われるようになっていった言語で、Androidアプリの標準開発言語です。
CとC++はAndroidアプリというよりはAndroid OSの低レベルの開発やAndroidを組み込みのOSとしてカスタマイズするときに利用される言語です。JavaやKotlinも同じ用途で使われていることもあります。
C# / Unityはゲームアプリの開発、Dart / FlutterとJS / React NativeとRust / Tauriはマルチプラットフォーム対応のアプリとして開発するときに用いられています。

この記事ではKotlinを使うことを想定して進めます。

## エディタ
KotlinでAndroidアプリを書く場合、基本的に[Android Studio](https://developer.android.com/studio?hl=ja)を使います。宗教上の理由でVSCodeを使いたい場合はVSCodeでも可能ですが、Android Studioの方が負荷状況のモニタリングなどの開発者向けのサポートを強く受けられます。

この記事ではエディタのダウンロードや使い方は紹介しませんが、ここ以後ではダウンロードとセットアップが完了してAndroid Studioを利用できるようになっているものとして進めます。

## Androidアプリの開発者向けの情報
Androidは先に見たように毎年新しいバージョンが出る進化が早いOSです。そのため、開発者に向けても大量の情報が発信されています。[Developper向けの公式サイト](https://developer.android.com/?hl=ja)だけでなく、簡単なアプリを自力で開発できるようになれる程度には充実している[トレーニングコース](https://developer.android.com/courses?hl=ja)、アーキテクチャの実装例を実際のソースコードで確認できるリポジトリの[architecture-samples](https://github.com/android/architecture-samples)や[nowinandroid](https://github.com/android/nowinandroid)があります。

もちろん本もいくつか出ています。
出版社からは、バージョン7.0の頃と少しAndroidのバージョンが古いですが、Androidの仕組みに関しては[Androidを支える技術〈I〉 60fpsを達成するモダンなGUIシステム](https://www.amazon.co.jp/dp/4774187593)や[Androidを支える技術〈II〉 真のマルチタスクに挑んだモバイルOSの心臓部](https://www.amazon.co.jp/dp/4774188611)があり、iOSなども混ざっていますがアクセシビリティに関しては[モバイルアプリアクセシビリティ入門 iOS＋Androidのデザインと実装](https://www.amazon.co.jp/dp/4297146029)が出版されています。
個人やサークルからは[BOOTH](https://booth.pm/ja/browse/%E6%8A%80%E8%A1%93%E6%9B%B8?q=%E6%8A%80%E8%A1%93%E6%9B%B8+Android)や[技術書典](https://techbookfest.org/market/search?q=Android)などで、最新のバージョンについての解説や、最近リリースされた新機能やツールの解説、普段Androidアプリを開発している人が開発時に気を付けていることや使っている開発手法紹介、などの内容の本が出ています。


# Androidアプリの開発フロー
さて開発に入っていきます。細かいところの順番は変わったり過不足はあるかもしれませんが、大筋は以下のようになります。

1. **要求定義**
  ここで作りたいものを決めます。
1. **要件定義**
  サポートするAndroidバージョンや必要な機能などを決めていきます。
  タブレット対応するのかや、アクセシビリティはどこまで対応するのか、もここで決めます。タブレットをサポートする場合は[2 ペイン レイアウトを作成する](https://developer.android.com/develop/ui/views/layout/twopane?hl=ja)のように分割された画面を考える必要がありますし、アクセシビリティで音声によるユーザー補助をサポートする場合TalkBackで読み上げる文言の対応をどの程度するかを考える必要があります。これらは後から対応するとなると対応が大変になるので、要件定義の段階で決めておくのが良いです。
1. **基本技術の選定と流行の情報収集**
  Androidアプリを書くだけでも、Kotlin, Flutter, ReactNative, Unity, Tauriといろいろ方法があるため、どの言語・フレームワークを採用するかを決めておく必要があります。また、これまで開発に利用していた言語であっても、昔と比べてより良い方法が提供されている場合もあるので、現在の流行の確認もしておきます。
  検証も忘れずにしておきます。選んだ技術によってはコアな機能の実装ができそうにないこともあるので、問題ないかの検証はしておくといいです。
1. **アプリ利用者のユースケースをできるだけ考えて、そのユースケースが実現できるようにフローやデザインを決定**
  Androidの場合、スマホのサイズだけでもいろいろなサイズがありますが、タブレットの対応をする場合はさらに想定すべきサイズが増えます。スマホのサイズ差程度の多少違うぐらいなら表示要素の多少の間延びを許せばデザイン上問題ないことも多いです。しかし、タブレット対応を考えると、左側にリストで右側に選択されたアイテムの詳細画面といったタブレット用の画面を採用することを考えていく必要が出てくるかもしれません。スマホ（必要ならタブレット）の各サイズで利用したいユースケースを実現できるように配置できるかを考慮して設計しておく必要があります。
1. **アプリの規模感の把握**
  アプリが長寿命ならメンテしやすい構造を考える必要があります。長寿命であればあるほどDIやテストなどが必要になります。
1. **アーキテクチャの決定**
  [アプリ アーキテクチャ ガイド](https://developer.android.com/topic/architecture?hl=ja)によると、[アーキテクチャに関する共通の原則](https://developer.android.com/topic/architecture?hl=ja#common-principles)を考えると、UI層、（必要なら）Domain層、Data層に分けたレイヤードアーキテクチャがモバイルアプリとして推奨されるアーキテクチャとなるようです。また、UI層ではUI状態の持ち方や画面の作り方でいくつか考慮することがあります。
    1. **アプリ全体のアーキテクチャ**
      KotlinならMVC, MVP, MVVMなどがあります。最近のGoogleはMVVMを推しているようです。
    1. **UIのアーキテクチャ**
      Kotlinで実装する場合、現在AndroidではViewを作るには昔ながらのXMLと最近出てきたJetpack Composeの２つの方法があります。XMLならアプリ全体のアーキテクチャに何を使ってもよいですが、Jetpack Composeを採用する場合アプリ全体のアーキテクチャは基本的にMVVMになります。
1. **アーキテクチャの実現の際に使う周辺技術の決定**
  APIを使うなどでネットワークを使う場合[Retrofit](https://square.github.io/retrofit/)を使う、DBを使う場合[Room](https://developer.android.com/jetpack/androidx/releases/room?hl=ja)を使うなど、必須となる機能に使うライブラリをここで決めます。6で決めたアーキテクチャによってはライブラリがサポートしていないことがあるので注意が必要です。
1. **使いそうなモデル（UI層、Domain層、Data層）を簡単でいいので設計してみて矛盾が起きないか確認**
  各層を意識してそれぞれでモデルなどを用意して仮実装してみます。それで依存関係などで矛盾がないかを確認しておきます。
1. **プロジェクト作成**
  Android Studioのプロジェクト作成からプロジェクトを作成します。namespaceやアプリ名、サポートするAndroid OSのバージョンを指定して作成します。
  このとき2点注意することがあります。
  １点目はnamespaceとアプリ名です。Androidアプリのプロジェクトでは大量のファイルがnamespaceやアプリ名を使ってプロジェクト作成時に生成されます。そのためnamespaceやアプリ名をリネームしようとすると対応漏れが発生するかもしれません。また、namespaceにexample.comを使うとアプリの公開で使えません。なので、Google Playで公開をすることを考えているなら、example.com以外を使った適当な名前にする必要があります。
  2点目は6で決めたUIのアーキテクチャに沿って初期設定されたテンプレートが用意されていることです。間違ったテンプレートを用意すると設定値の変更が大変になります。
1. **（必要なら）モジュール分割**
  アプリが大規模、もしくは長寿命になりそうならここでモジュールの分割を行っておきます。
  モジュールの分割を行うことで、並行ビルドや、キャッシュによるビルドスキップ、IDEによるヒント時の参照されるスコープの制限、などのメリットを受けることができます。
  モジュールの分割については[こちらの記事](https://zenn.dev/kzt/articles/e35d0a3c36d247)が参考になると思います。
1. **アーキテクチャの実現に向けての初期設定**
  プロジェクトを作成して基本的な設定が終わったら、実装でベースとなるアーキテクチャの設定を行います。必要なインターフェースを作ったり、想定しているデータフローやイベントフローが回るようにいろいろと準備します。
1. **（必要なら）ビルドタイプの制御やプロダクトフレーバーの作成**
  ビルドタイプはdebugとreleaseの二つが用意されており、それぞれデバッグビルドとリリースビルドで利用する設定を指定するのに使われます。debugの時は難読化や署名を行わず、releaseの時は難読化と署名を行うように設定することが多いです。
  プロダクトフレーバーはビルドコマンドのパラメータとして指定できる値で、ビルド時の変数の切り替えなどができます。例えばdevelop, staging, releaseとプロダクトフレーバーを用意して、それぞれ開発用かステージング用か本番用かでアプリ名などを変更したりすることに使います。また、タブレット用とスマートフォン用とビルド設定を分けるときに使ったりもします。
1. **（必要なら）DIの導入**
  テスタビリティを考えた実装をする場合、テスト時にモックで置き換えるためにDIをしたいと考えると思います。ほかにもいろいろなところでユースケースインスタンスを作成したくないとか、ライフサイクルを考慮したシングルトンを作りたいとか、あると思います。そのためのDIの利用のための準備をここで行っていきます。
  Androidでは[Hilt](https://developer.android.com/training/dependency-injection/hilt-android?hl=ja)というライブラリがDIライブラリのデファクトスタンダードになっています。Hiltは長年使われていることもあり、Qiitaの記事だけでも十分利用できるようになるほど十分な情報があるライブラリです。
1. **機能や画面の実装。並行してテストを書いていく**
  アーキテクチャに則りながら各機能や画面を実装していきます。一緒にテストも書いていきます。
1. **アプリアイコンの設定**
  アイコンがないリリースもできないので、アプリのアイコンを忘れずに設定しておきます。本当はプロジェクトを作成した後すぐに対応してもいいくらいですが、開発開始時はアイコンが決まっていないことが多いのでこの位置です。Push通知などで使うアイコン設定もここでまとめて行っておきます。
  アプリアイコンの設定については、[こちら](https://developer.android.com/codelabs/basic-android-kotlin-compose-training-change-app-icon?hl=ja)をご覧ください。
1. **品質の向上**
  一通り実装が終わった後は、長い画面でスクロールをしたときに60fpsは問題なくでるのか、個人情報漏洩の対策などセキュリティは問題ないか、アプリを利用した時の想定されるフローを行ったときに対応漏れはないのか、など品質を確認し、問題なくなるまで向上させていきます。テストが書いてあるなら、テストを実施してエラーが検出されるので検出されなくなるまで修正していきます。
1. **（必要なら）アプリを申請する**
  Androidアプリの場合、公開する前にアプリを申請して審査をしてもらう必要があります。アプリをストアで公開しないなら、申請は不要です。初めてそのアプリを申請する場合はアプリなどのストア情報の初期設定など、いろいろ手間がかかる作業でもあります。
  Androidの場合のストアはご存じ[Google Play](https://play.google.com/store/apps?hl=ja&pli=1)というストアです。しかし、申請などの管理機能を使う場合は、[Google Play Console](https://developer.android.com/distribute/console?hl=ja)というサイトを使うことになります。このサイトを使うには開発用のGoogleアカウントでログインする必要があります。ログインしたアカウントが開発用でない場合はそのタイミングで登録をすることもでき、登録したときに25米ドルかかりますがそれ以降追加の費用はかかりません。
  Google Play Consoleの使い方の詳しいことはほかの記事に任せますが、公開用にリリースビルドしたものをGoogle Play Consoleにアップロードしてバージョンや説明などの必要な項目を入力することで申請ができます。この申請作業はアプリを初めて公開する時だけでなく、アップデートするときも必要になります。
1. **（必要なら）アプリを公開する**
申請してリリースして問題ないとなった後は公開することができるようになります。公開するとしばらくしてからアプリがGoogle Playからダウンロード／アップロードできるようになります。

# 最近の推奨項目
Androidは15年以上開発が続いているので推奨されている事項も整備されてきます。いくつか紹介します。

## Marterial Design
昨今のAndroidのデザインはGoogleが提唱した[Material Design](https://m3.material.io)というデザイン指標に従っています。M1, M2と来て現在ではM3という3つ目のバージョンとなっています。Material DesignはFlutterでも採用されている指標となります。Material Designを採用するとUI/UXを意識した上で質感や統一感を取り入れたデザインとなります。これによりデバイスの設定値が変わったり別のアプリから切り替えられたりしても違和感なく操作ができてストレスフリーなアプリが出来上がります。

## UIレイヤーとDataレイヤー
[アプリ アーキテクチャ ガイド](https://developer.android.com/topic/architecture?hl=ja)によると標準的なAndroidアプリの場合、最低限UIレイヤーとDataレイヤーを用意するのが推奨されています。UIレイヤーは画面に表示することに関して責任を持ち、Dataレイヤーはデータを管理することに責任を持ちます。ビジネスロジックはDataレイヤーに含まれますが、DomainレイヤーをUIレイヤーとDataレイヤーの間に設けて3層にし、このDomainレイヤーにビジネスロジックを作成することで分けて管理する方法もあります。このようにレイヤーを分けることでアーキテクチャに関する共通の原則である「関心の分離」「UIをデータモデルで操作する」「信頼できる唯一の情報源」「単方向データフロー」を考慮した実装をすることができるようになります。

## Jetpack Compose
[Android アーキテクチャに関する推奨事項](https://developer.android.com/topic/architecture?hl=ja)によると、最近のAndroidは[Jetpack Compose](https://developer.android.com/compose)を推奨しています。Jetpack ComposeはFlutter的な宣言的UIを採用しており、FlutterのようにソースコードでUIを構築していくことができます。条件によってはですがHot Reloadも可能です。また、Jetpack Composeを使う場合Kotlinを使うことが必須になってきますが、KotlinはJavaより安全であることに加え、KotlinのコルーチンはAndroidアプリ特有のライフサイクルなどと相性が良いのでほとんど困らないと思います。
Jetpack Composeは2021年に出てきた比較的新しいUIツールキットですが、従来のXML方式の命令型ではなくFlutterのような宣言型で書くことができる上に、XML方式で実装したUIに相当する快適な動作を実現できます。2024年になっても改善が行われているので、まだまだ快適さは上がっていきます。また、XML方式の時で難しかったアニメーションも簡単に実装できるようになっているので、初心者が今からAndroidアプリを始めるときにXML方式を採用する理由はないかなと思います。
Jetpack ComposeではXML方式のときのWidgetをComposableと呼びます。Material DesignのM3に準拠したJetpack Composeの標準Composableについては[androidx.compose.material3](https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary)を参照してください。
Jetpack Composeについての書籍[詳解 Jetpack Compose ── 基礎から学ぶAndroidアプリの宣言的UI](https://www.amazon.co.jp/dp/4297144883)が最近でました。[公式のチュートリアル](https://developer.android.com/develop/ui/compose/tutorial?hl=ja)を見てよくわからなかった人や、もっと深く知りたい人、チュートリアルより先の[pathways](https://developer.android.com/courses/pathways/compose?hl=ja)を見てよくわからなかった人や、まとまった情報源として書籍が欲しい人、などなど有用な情報源になってくれる書籍となると思います。

# まとめ
Androidアプリ開発の全体像が伝わるように書いてみましたがどうでしょうか。自分もほぼ初心者のような者なので間違った記述があるかもしれませんが、間違いないよう心がけたつもりです。間違いがあれば指摘してください。自分も含め他の初心者の糧となります。