Androidアプリ作りに使った技術をまとめてみた[UltraSpeedMemo編]

　自作Androidアプリ作りに使った技術（ツールやライブラリなど）をピンからキリまでまとめてみました。
　<u>[こちら](https://play.google.com/store/apps/details?id=ja.gr.java_conf.asickohyaena.ultraspeedmemo)</u>のアプリで使った技術を小さなものから大きなものまで全て羅列しています。アプリを実際に触りながら読んでみると参考になると思います。

ブログの方にも書いています。ほとんど内容が同じですが、何かあれば参照してください。
https://5hyn3.github.io/posts/ultraspeedmemo-tech/

---

# 目的

　Androidアプリ作りについて基礎は勉強したけども、そこから先については右も左も分からない開発者に対して、ここを見て気になったところをググれば、アプリを0から作れる程度の知識を得られるインデックスを提供すること。
詳細は書かずに、ググるのに必要な各種の名前と、一文程度の概要を記述する。

---

# 想定する読者

- Androidアプリ開発の基礎を学んで、その先の知識を身に付けたい開発者
- このアプリを作った時の詳細を忘れた数ヶ月後の自分

半分くらいは自分のためのメモ書きです

---
# アプリについて

こんな感じのアプリです。通知欄から即座にメモを保存できることが特徴のアプリです。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://t.co/kgbaIyVYIU">https://t.co/kgbaIyVYIU</a><br>こういうアプリ作ってます</p>&mdash; shyne (@5hy_n3) <a href="https://twitter.com/5hy_n3/status/1078634548374646785?ref_src=twsrc%5Etfw">2018年12月28日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<a href='https://play.google.com/store/apps/details?id=ja.gr.java_conf.asickohyaena.ultraspeedmemo&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Google Play で手に入れよう' src='https://play.google.com/intl/us-en/badges/images/generic/ja_badge_web_generic.png'/></a>

---


# Androidアプリ作りで使ったツール・ライブラリ

## IDE

- AndroidStudio

まずはこれが無いと始まらない。

## 言語

- Kotlin

　以前はJavaで開発されていたが、今から開発するのであればより開発効率の高いKotlinを使うことを推奨する。

## UI周り

- androidx

　互換性を保ちながら、UI周りをいい感じにしてくれるライブラリ。以前はSupportLibraryと言う名前で提供されていた。

- AppCompatActivity

　androidxに入っている。下位互換性を保ったまま最新の機能が使えるActivity。Activityで何か作るなら大抵はこれを使えば間違いない。


- Navigation Architecture Component 

　現在α版のライブラリ。Androidの画面遷移周りをよしなにしてくれる。遷移グラフを定義することで、画面と画面のつながりを視覚的に理解しやすく出来、お好みで遷移アニメーションや型付の引数渡しなどができるようになる。

![Screenshot from 2019-01-03 19-08-02.png](https://qiita-image-store.s3.amazonaws.com/0/105287/d731d3e3-bac7-0176-3106-535e5c86bb79.png)

<div style="text-align:center;">
Navigation Architecture Componentを利用することで遷移が視覚的にわかりやすくなる
</div>

- Fragment
  
　Activityでは対処できない、無数の画面サイズに対応するために生まれた仕組み。上記Navigation Architecture Componentを活用するために、本アプリはSingle Activity, Many Fragmentな作りになっている。 


- MotionLayout  

  　現在α版のライブラリ。Androidのアニメーション周りをよしなにしてくれる。アニメーション開始時のConstraintと、開始後のConstraintを定義し、その他いくつかのパラメータを設定することでアニメーションを行ってくれる。  
  　このアプリでは、以下のように、FABのhide/show的なポジションのメソッドがないMaterialButtonに対して、それっぽい動きをさせるために使用している。  
  　一点落とし穴として、MotionLayoutを使用している際、AndroidAppBundleを利用すると、アニメーションが動作しなかった。どうもMotionを定義したXMLがビルド時に省かれてしまったようで、通常のAPKを生成することで動くように出来た。

![untitled.gif](https://qiita-image-store.s3.amazonaws.com/0/105287/7eb91283-73d1-d769-5856-5128b98bef03.gif)


- DataBinding
  
　面倒なView層の作業（テキストをセットしたり、onClickの動作を紐づけたり...）をXML上で出来るようにしてくれる仕組み

- ViewModel  

　Androidのライフサイクルを気にせずデータを保持できる仕組み。onSaveInstancestateでstateを保存してonRestoreInstanceStateで復元するような面倒なコードを書く必要がなくなる

- RecyclerView
  
　Androidにおいて、多数ある項目を並べて表示するために使われるUIコンポーネント。名前の通り、単にリストを表示するというものではなく、Viewをリサイクルして表示する必要のあるもの全般に使える。

- bindingcollectionadapter
  
  https://github.com/evant/binding-collection-adapter  
　上記RecylerViewはAdapterを書くのが面倒だが、DataBindingを活用することで、XML上でデータとViewの紐付け方を定義することで、Adapterを全く書かなくてもRecyclerViewが使えてしまうライブラリ。実際、本アプリはRecyclerViewのAdapterを一行も書いていない。非常に楽

- constraintlayout

　以前はRelativeLayoutとかLinearLayoutとかでレイアウトを組むことが多かったが、今はだいたいこれ一つでサクサク作る。


- material-design-icons

　Apache2.0ライセンスで使えるアイコンを提供している。本アプリで使用しているアイコンからアプリ自体のアイコンまで、全てここにあるものを使って作成されている。

https://material.io/tools/icons/?style=baseline

## バックグランドサービス

- Service

　バックグラウンドで何かしらのタスクを実行するのに必要なもの。Oreo以降からバックグラウンドサービスの扱いが厳しくなり、扱いが若干面倒になった。

- startForegroundService

　Oreoより前はstartServiceでバックグラウンドサービスを起動できたが、Oreo以降はこちらで起動した上で、制限時間内に通知を表示したりstartForegroundを呼んだりしないとクラッシュしてしまう。


## 通知周り

- NotificationChannel

　Oreo以降で導入された機能。全ての通知は予め生成したチャンネルを割り当てる必要がある。ユーザーはこのチャンネル単位で通知の表示・非表示を切り替えることができる。

- NotificationCompat

　下位互換性を保ちながらNotificationを扱えるようにしてくれるライブラリ。上記チャンネルの影響で通知を表示する際のコードにもバージョン分岐が発生してしまうが、これを使うことでそういった面倒な部分を回避できる。

- DirectReply
  
　Android7.0以降で使えるようになった、通知上でテキストを入力し、アプリでその入力を受け取れる仕組み。これのために、本アプリを扱える端末はだいぶ限られてしまっている。

## データ永続化
- Realm

　モバイルアプリケーション向けデータベース。いわゆるNoSQLで、オブジェクト指向な作りになっている。SQLiteよりも高速で動作する。若干癖があるが、慣れるとSQLiteよりも簡単に扱えると思う。

## ビルド周り
- applicationIdSuffix

　Gradleで使用することでapplicationIdにsuffixを付けられる。これによって、デバッグ時のアプリとリリース時のアプリのapplicationIdを別にできる。

- main.java.srcDirs += 'src/main/kotlin'

　Kotlinを使用する際に、デフォルトで存在するJavaディレクトリ以下ではなく、kotlinディレクトリ以下をソースとして認識させたくなった際のおまじない。

## その他

- play-services-oss-licenses

　アプリ内で使用している各種ライブラリのOSSライセンスを表示するActivityを作ってくれる。

- play-services-ads

　広告を貼って収益化するのに必要。合わせて、admobというサービスを利用する必要あり。

- KOIN

　DIに使っている。各Activityで書きがちなViewModelの初期化だったり、Repositoryの生成だったり、そういうお決まりのボイラープレートを1ヶ所に纏め、コード量を減らすと共に、DIによるコンポーネントの差し替えの仕組みを提供できる。