Android初学者用まとめ

はじめてAndroid開発を行って学んだことをまとめました。
最初は、[はじめてのAndroidプログラミング 第4版 | 金田 浩明 |本 | 通販 | Amazon](https://www.amazon.co.jp/dp/4815601143/ref=cm_sw_r_tw_dp_U_x_ejxQEb7Q0AMYJ)を読むのがすごくお勧めです。 
数時間ですらすら読めてAndroid開発の特徴をつかめました。

# アーキテクチャ
## Androidのアーキテクチャを考える時
これが丁寧で分かりやすい。
[Androidアーキテクチャことはじめ ― 選定する意味と、MVP、Clean Architecture、MVVM、Fluxの特徴を理解する - エンジニアHub｜若手Webエンジニアのキャリアを考える！](https://employment.en-japan.com/engineerhub/entry/2018/01/17/110000?amp=1)  

公式のアーキテクチャガイド
[アプリのアーキテクチャ ガイド  |  Android デベロッパー  |  Android Developers](https://developer.android.com/jetpack/docs/guide?hl=ja#mobile-app-ux)  

公式のサンプルコード
[GitHub - android/architecture-samples: A collection of samples to discuss and showcase different architectural tools and patterns for Android apps.](https://github.com/android/architecture-samples)  

### MVVM
MVVMを調べるときに参考にしたサイト
[Android Architecture Components 初級 （ MVVM + LiveData + Coroutines 編 ） - Qiita](https://qiita.com/Tsutou/items/69a28ebbd69b69e51703)  
[AndroidのMVP・MVVMの人気サンプルプロジェクト2個の実装方法を読む - Qiita](https://qiita.com/takahirom/items/0ab91188dd8f27d99ac0)  
[Android Data Binding + MVVMパターンのサンプルを書いてみた - Qiita](https://qiita.com/amay077/items/b5c788bb3ee9ff84d9b4)  


# コーディング規約
[Various Android Coding Style2016 - Qiita](https://qiita.com/Reyurnible/items/c2c0f7150d338a49de86)  
[Androidコードディング規約 - Qiita](https://qiita.com/Reyurnible/items/2de397b80391189af8e4)  
リソースに関するコーディング規約について
[Android アプリのリソース定義ポリシーを整備した話 - クックパッド開発者ブログ](https://techlife.cookpad.com/entry/android-resource-policy)  

# プロジェクト
[プロジェクトの概要  |  Android デベロッパー  |  Android Developers](https://developer.android.com/studio/projects?hl=ja)  
## プロジェクト構成	
[Androidのパッケージ構成について考えてみた - Qiita](https://qiita.com/kobakei/items/e8452d04f6991be3498a)  
## リソースフォルダ
mipmapとdrawableの違い
[Androidのmipmapとdrawableについて - Qiita](https://qiita.com/gamako/items/c6b8aa43660ff6e76c14)  
## モジュールの呼び出し
AARファイルを使ってモジュールの呼び出しを行う。
AARファイルはAndroid Studio専用のライブラリ。
[Android Studio で AARファイルを作って読み込む - Qiita](https://qiita.com/izuki_y/items/bd61a2cf8473bf6bd9fb)  
## ドキュメントコメント(Kotlin)
Kotlinの場合、KDocというAPIドキュメントを使って実現する。
[Documenting Kotlin Code - Kotlin Programming Language](https://kotlinlang.org/docs/reference/kotlin-doc.html)  
[KDoc 書き方メモ(Kotlin のドキュメンテーションコメント) - Qiita](https://qiita.com/opengl-8080/items/fe43adef48e6162e6166)  
出力は、Dokkaというツールを使う。
[GitHub - Kotlin/dokka: Documentation Engine for Kotlin](https://github.com/Kotlin/dokka)  


# ライフサイクル
ライフサイクルを制すものはAndroid開発を制すと言われるくらい大切な概念。
スマートフォンは割込み処理が多くメモリが少ないためメモリの開放が行われるため、その対応のためにライフサイクルを考慮した設計が必要になる。
[アクティビティのライフサイクルについて  |  Android デベロッパー  |  Android Developers](https://developer.android.com/guide/components/activities/activity-lifecycle?hl=ja)  
[アクティビティのライフサイクル - Androidプログラミング入門 | JavaDrive](https://www.javadrive.jp/android/activity/index2.html)  

以下が主なライフサイクルの流れになる。
__アクティビティが表示されて実行中になる__
onCreate => onStart => onResume

__別のアクティビティが表示される__
onPause => onStop
再びアクティビティが表示されるときはonResumeに戻る。
例えば、ホームボタンを押したとき

__非表示になって再表示される__
onStop => onRestart => onStart

__アクティビティが終了する__
onPause => onStop => onDestroy
例えば、戻るボタンでアプリを消したとき
画面を回転させたときもonDestroyは実行され、onCreateが実行される。Fragmentも破棄される。
この時、引数Bundleが入っている。

上記以外にも様々なメソッドが実行されている。
[Activity  |  Android デベロッパー  |  Android Developers](https://developer.android.com/reference/kotlin/android/app/Activity) を確認しよう。


## Fragment
画面の一部を使いまわすときに使う。
Fragmentのライフサイクルは、Activityとは異なる。
Fragmentが非表示なった時は、バックスタック(スタック構成でFragmentを一時的に保存しておく機能)に入りonPauseが実行される。
バックスタックにはいったFragmentは再生成せず取り出し可能になる。
[フラグメント  |  Android デベロッパー  |  Android Developers](https://developer.android.com/guide/components/fragments.html)  
[続: Fragment使う人に最低限、知っておいて欲しいこと - めがねをかけるんだ](https://blog.keiji.io/2015/12/mincomi-adventcalendar-24.html)  
## ActivityやFlagment間でのデータをやり取り
ActivityやFlagmentは、メモリが少なくなったり画面を回転させると再生成する場合がある。その時、メンバー変数などの値が消えるためArgumentにデータを保管する必要がある。
保持されるデータはBundle型になる。
Argumentの処理はコンストラクタではなく、スタティックメソッドの中で行う。
破棄されたFramgmentが再び生成されるときは空のコンストラクタが実行されるためコンストラクタで初期化するとアプリが落ちてしまう。
[Y.A.M の 雑記帳: Android　Fragment で setArguments() してるサンプルが多いのはなぜ？](http://y-anz-m.blogspot.com/2012/04/androidfragment-setarguments.html)  
最近は、SafeArgsを使ってActivityやFlagment間でデータをやり取りするみたいです。
[Navigation SafeArgsを使って画面遷移でパラメータを渡す - ticktakclockの日記](https://ticktakclock.hatenablog.com/entry/2020/02/02/170615)  
[デスティネーション間でデータを渡す  |  Android デベロッパー  |  Android Developers](https://developer.android.com/guide/navigation/navigation-pass-data?hl=ja)  


## マルチスレッド
画面に関する処理は全てメインメソッドで行う必要がある。
Handlerで別スレッドで行いたい処理を委譲することで画面の処理はメインメソッドに渡すようにしてやる。
[Handlerクラスの正しい使い方（Androidでスレッド間通信） - ちくたく](https://sankumee.hatenadiary.org/entry/20120329/1333021847)  

# データの保存
データの保存の種類について
[データとファイルのストレージの概要  |  Android デベロッパー  |  Android Developers](https://developer.android.com/guide/topics/data/data-storage.html?hl=ja#db)  
[【Android】データの保存と共有について - Qiita](https://qiita.com/s_emoto/items/aeacf06111b9469176b1)  

## 内部ストレージへの保存
内部ストレージに保存した場合、保存元のアプリだけアクセスできる。
アンインストールすると、内部ストレージのデータは消える。
APIでファイル読み書きが可能。
[内部ストレージにファイルを保存する  |  Android デベロッパー  |  Android Developers](https://developer.android.com/training/data-storage/files/internal)  

### SharedPreferences
データの規模が小さくて構造的なデータではないデータを保存するのに適する。
簡単なKey-Valueしか対応できない。
[SharedPreferences  |  Android デベロッパー  |  Android Developers](https://developer.android.com/reference/android/content/SharedPreferences)  
## DB
AndroidではSQLiteが標準のDBで用意されている。
[SQLite を使用してデータを保存する  |  Android デベロッパー  |  Android Developers](https://developer.android.com/training/data-storage/sqlite?hl=ja)  
DBの設定などアプリケーション実行時に処理することは、Applicationクラスを継承したクラスを作って、Manifest.xmlに追記する。

[Applicationクラスを継承して、データの共有をする。 | TechBooster](https://techbooster.org/android/application/2353/)  

## 音を再生する
### SoundPool
短めの音を流す時に使う。
streamTypeを分けることで複数の音声を同時に鳴らすことが出来る。
音データの読み込みはメモリを多く消費するためonResumeでロードし、onPauseeでメモリ開放する。
APIバージョン21以降ではSoundPool.Bolderクラスを使うことが推奨されるため分岐でバージョンごとに処理を変える。
[SoundPool  |  Android デベロッパー  |  Android Developers](https://developer.android.com/reference/android/media/SoundPool)  

### MediaPlayer
長めの音を流す時に使う。
[MediaPlayer の概要  |  Android デベロッパー  |  Android Developers](https://developer.android.com/guide/topics/media/mediaplayer?hl=ja)  

### オーディオフォーマット
OGGがおすすめ。
どのバージョンのOSでも対応している。
[Androidで音声扱うときはoggにしとくのが良いっぽい - Hacking My Way 〜 itogのhack日記](https://itog.hatenadiary.org/entry/20100418/1271593207)  


# UI
## アプリリソースについて
### ラベル名やメッセージなどの文字列
res/values/strings.xmlに登録する。
### 色
res/values/colors.xmlに登録して参照する。
### 寸法値
res/values/dimens.xmlに登録して参照する。
Androidは解像度が異なると文字・マージンの大きさが同じでも見え方が異なるためdimens.xmlを解像度ごとにフォルダを分けて管理する。
[Android開発者のみなさん、レイアウトを作るとき、文字やマージンの大きさって端末間の差をどうやって対応していますか？](http://gucci1208.com/android%E9%96%8B%E7%99%BA%E8%80%85%E3%81%AE%E3%81%BF%E3%81%AA%E3%81%95%E3%82%93%E3%80%81%E3%83%AC%E3%82%A4%E3%82%A2%E3%82%A6%E3%83%88%E3%82%92%E4%BD%9C%E3%82%8B%E3%81%A8%E3%81%8D%E3%80%81%E6%96%87-344.html)  
### 文字の大きさの単位
sp
ユーザーのAndroid設定が反映された文字列の大きさになる。
dp
ユーザーのAndroid設定によらず固定になる。
[【Android】いまさら聞けないdp入門 - Qiita](https://qiita.com/nein37/items/0a92556a80c6c14503b2)  

### スタイル
res/values/styles/styles.xmlに登録して参照する。
[アプリリソースの概要  |  Android デベロッパー  |  Android Developers](https://developer.android.com/guide/topics/resources/providing-resources?hl=ja)  
### 画像
res/values/styles/drawables.xmlに登録して参照する。
### アイコン
解像度に合わせて6種類用意する。
Android4.2以降は、アダプティブアイコン(拡大縮小などに対応)に対応するためres/mipmapに置くだけで良い。
[各種のピクセル密度をサポートする  |  Android デベロッパー  |  Android Developers](https://developer.android.com/training/multiscreen/screendensities?hl=ja#top_of_page)  

ベクター形式の画像を使えば軽く拡大縮小で劣化しないのでおすすめ。
ベクター形式の画像はAndoroid 5.0からの対応するため、それ以下のバージョンに対応するにはサポートライブラリを使用する。
build.gradleファイルにサポートライブラリを使用する設定を行う必要がある。
[さまざまな密度に適用可能なベクター グラフィックの追加  |  Android デベロッパー  |  Android Developers](https://developer.android.com/studio/write/vector-asset-studio?hl=ja)  

#### ベクター形式の画像
ボタンに使うAndroidで統一性を持たせる＆軽いためAndroid Studioで提供されているベクター形式の画像が良い。
使い方
[[Android] VectorDrawableでベクター形式のアイコンを描画する - JoyPlotドキュメント](https://joyplot.com/documents/2018/08/03/android-vector-drawable/)  
[アプリ内ボタンにマテリアルデザインアイコンを使う [Android] - Qiita](https://qiita.com/hoshiume11/items/b9925d105957d827011a)  

ベクター形式の画像の一覧
[Icons - Material Design](https://material.io/resources/icons/?style=baseline)  

### Button
`AppCompat.Button`を使う。
[Androidのボタンスタイルを理解する - Qiita](https://qiita.com/ushi3_jp/items/5a77afe89ab876046eb1)  

`MaterialButton`を使う。
[Goodbye `shape` - AndroidのMaterialButtonがすごい良かった話 - Qiita](https://qiita.com/Reyurnible/items/20457d2ef9572b0eee94#materialbutton)
[android - Material design button with border - Stack Overflow](https://stackoverflow.com/questions/37395697/material-design-button-with-border/51486054)
[Buttons - Material Components for Android](https://material.io/develop/android/components/buttons/)  

MaterialButtonを使うときは、以下のようにandroid:textApperance属性を追加しないとエラーが起こります。

```xml
    <com.google.android.material.button.MaterialButton
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="@style/TextStyle"
        app:strokeColor="@color/colorPrimary"
        style="@style/Widget.MaterialComponents.Button.OutlinedButton" />
```

```xml:styles.xml
    <style name="TextStyle" parent="@android:style/TextAppearance">
        <item name="android:textSize">20sp</item>
        <item name="android:textColor">#797979</item>
    </style>
```

## AppTheme
アプリケーション全体のスタイルを統一する仕組みとしてテーマというものがあり、新規プロジェクトではAppThemeという名前のテーマが指定されている。
アクションバーの見た目を変えたりするときはこのあたりを検索するとよい。
[スタイルとテーマ  |  Android デベロッパー  |  Android Developers](https://developer.android.com/guide/topics/ui/look-and-feel/themes?hl=ja)  

## Layout
[Androidのレイアウト👶初心者向けざっくり理解 - Qiita](https://qiita.com/mii-chang/items/ee965c1e8826d4e59414)  
### Constraint Layout
要素に制約を持たせて表示することが出来るレイアウト。
Autoconnect
自動で制約を追加してくれる。
Barrier
複数のViewの端を表すガイドラインを作ることができる。これを使って長さの違う複数のViewの端から別のViewをくっつけたりすることが出来る。
Group
複数のViewをまとめることができる。一気の非表示にしたい時などに使う。
Chain
Viewの間隔を均等に配置したい時に使う。
[ConstraintLayoutをもう少し深く知ってみる - Qiita](https://qiita.com/takahirom/items/97818748e2c2059a2536)  

### FrameLayout
Viewを重ねて表示することが出来るレイアウト。

### レイアウトのインクルード機能
レイアウト定義されたXMLファイルに別のレイアウト定義したXMLファイルを読み込む。
[Androidで個人的によく使うlayout系設定チートシート - Qiita](https://qiita.com/k_keisuke/items/fa56434dc11ec6608f67)  


## ImageView
scaleTypeの設定で表示方法が変わる。
[【ImageView】ScaleTypeと表示画像の対応表 - Qiita](https://qiita.com/tkhs0604/items/76bd3c979ae3c0c1570c)  

## 一覧表示を行う
### ListView
簡単に扱えるが大量のデータ表示には向かない。現在はレガシー扱い。
### RecyclerView
大量のデータ表示やスクロール表示ができる。
項目の配置はレイアウトマネジャーによって決定する。データはアダプターを介して取得する。
データ項目には固有のIDを持っている。IDを使ってデータ更新を変更のあった項目だけ更新することが可能になり、画面のちらつきを軽減する。
項目がタップされたことは、アダプターからアクティビティへ通知するコールバックにて対応する。


## スワイプしてViewを入れ替える
スワイプ操作でViewを切り替えるには、ViewPageとPageAdapterを使う。
### ViewPage
必要なViewをPageAdapterに要求し、受け取ったViewを表示する。
### PageAdapter
Viewの生成を行い、ViewPageに渡す。

## ボタンの同時押し禁止
Constraint LayoutのsplitMotionEventsをfalseにすればボタンタップによって発生するイベントは1つになる。
[Androidでボタンの同時押し防止 | backport](https://backport.net/blog/2017/02/05/android_split_motion_events/)  

# 機能実現方法
## 他のアプリを呼び出して使う
### 暗黙的なインテント
こちらでは呼び出したい機能を指定するだけで、あとはAndroidシステムに起動するアプリを任せてしまう。
例えば電話やブラウザ起動、メール送信などAndroidシステムに任せられる。
[インテントとインテント フィルタ  |  Android デベロッパー  |  Android Developers](https://developer.android.com/guide/components/intents-filters?hl=ja)  
[Android Intentで画面遷移する(暗黙的Intent) | TechBooster](https://techbooster.org/android/application/8835/)  

## アラームなどある時間に処理を行う
Androidで非同期に発生するイベントはブロードキャストでインテントが送られる。
ブロードキャストするインテントとブロードキャストを行う時間を設定するAlarmManagerとブロードキャストを受け取るBroadcastReceiverで実現する。
指定したタイミングで発行するブロードキャストイベントはPrndingIntentクラスで作成する。
[[Android] AlarmManagerをBroadcastRecieverと使う](https://akira-watson.com/android/alarmmanager-timer.html)  

## 通知方法
Toastやダイアログなど通知方法が様々存在するので、用途に応じて使い分けよう。
[Android いろいろな通知の表示方法(Toast, Snackbar, Dialog) - Symfoware](https://symfoware.blog.fc2.com/blog-entry-2031.html)  
[[Kotlin] Androidにおける通知の送信と通知をタップしたときの処理 - JoyPlotドキュメント](https://joyplot.com/documents/2018/04/27/kotlin-android-notification/)  
### ダイアログ
DialogFragment
ダイアログを管理するフラグメントを使う。画面回転や戻るボタンの制御をしてくれる。
DialogFragmentとアクティビティのやりとりはコールバックを使う。
リスナーを介してDialogFragmentからアクティビティのメソッドを呼ぶ。
[ダイアログ  |  Android デベロッパー  |  Android Developers](https://developer.android.com/guide/topics/ui/dialogs?hl=ja)  

# Android Studio
## コピーライト
Android Studioならコピーライトを簡単に自動挿入できる。
[Android Studio で新規ファイル作成時に Copyright を自動挿入する | まくまくAndroidノート](https://maku77.github.io/)  

# その他
AndroidXは、新しいサポートライブラリ。API28以上から使用可能。
[AndroidX の概要  |  Android デベロッパー  |  Android Developers](https://developer.android.com/jetpack/androidx?hl=ja)  

UIで躓いた点などがまとまってて面白かった。
[Androidアプリを作ってから参考書を読んだら驚いた｜toconakis.tech](https://toconakis.tech/refafterapp/)