最近のAndroidアーキテクチャを勉強するために、はてブアプリを開発した(選定編)

趣味でAndroidアプリ開発は昔からちょこちょこやっていたのですが、割と最近まで仕事でAndroidネイティブ開発をする機会がなかなかありませんでした。

今回Androidのネイティブ開発の仕事をするにあたって、今イケてそうなAndroidの最新アーキテクチャやライブラリを使う勉強としたいと考え、その題材としてはてなブックマークのホットエントリ記事を読むアプリを作ってみました。

Google Playストアで公開中です。
[HotBook - はてブ記事がサクサク読める](https://play.google.com/store/apps/details?id=jp.kuluna.hotbook)

# 目標
- なるべくこれからスタンダードになりそうな開発手法でやってみよう
- API通信をするアプリを作ってみよう

# 作ったもの
![ezgif-2-fb6be1b734.gif](https://qiita-image-store.s3.amazonaws.com/0/44992/b932becd-4230-d042-a7e2-6ad0de92cdc4.gif)

全体的にダークテーマにしたのと、CoodinatorLayoutを使ってこれぞ今風のAndroidアプリっぽい感を出しました。

<img width="270" alt="device-2018-02-11-140320.png" src="https://qiita-image-store.s3.amazonaws.com/0/44992/ca151914-13a3-1880-0fee-e612617c437d.png">

ドメイン毎にJavaScriptを切ってブラウズできる機能をつけてみました。
AndroidのWebViewでjavaScriptを無効にできるという、これいつ使うんだという設定を初めて機能として組みました。

<img width="270" alt="device-2018-02-10-234956.png" src="https://qiita-image-store.s3.amazonaws.com/0/44992/1d43c23f-f7b3-1a09-4bb8-7670c1cffa5b.png">

もちろんブコメも見れます。

# 今のAndroidの開発ってどんなんだろう
Google公式が気の利いたライブラリをたくさん公開してくれたおかげなのか、割とGoogleのライブラリだけでもかなり良い感じのアプリが作れるようになっているようです。

今回アプリを作るうえで以下を選定してみました。
あ、IDEはさすがにAndroid Studio択一ですよね？


- 言語
  - kotlin
- アーキテクチャ
  - Android Architecture Components (Google公式のObserverサポート)
  - Data Binding (Google公式のMVVMサポート)
- 通信・モデル周り
  - Retrofit (HTTP通信)
  - moshi (JSON変換)
- View周り
  - Android Design Support Library (Google公式のUIライブラリ)
  - Picasso (画像周りをよしなにしてくれる)

その他関連ライブラリを含めたdependency一覧はこんな感じです。

```groovy
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.30"
implementation 'android.arch.lifecycle:extensions:1.1.0'
implementation 'android.arch.lifecycle:runtime:1.1.0'
implementation 'com.android.support:support-v4:27.1.0'
implementation 'com.android.support:appcompat-v7:27.1.0'
implementation 'com.android.support:cardview-v7:27.1.0'
implementation 'com.android.support:design:27.1.0'
implementation 'com.android.support:preference-v7:27.1.0'
implementation 'com.android.support:recyclerview-v7:27.1.0'
implementation 'com.squareup.moshi:moshi:1.5.0'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.squareup.retrofit2:converter-moshi:2.3.0'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
kapt 'android.arch.lifecycle:compiler:1.1.0'
kapt 'com.android.databinding:compiler:3.0.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
```

よく見てみるとGoogle公式とSquareのライブラリしか入ってないですね(笑)
この選定を含めた開発環境はこんな感じになりました。

- Android Studio3.0.1
- Android Support Library 27.1.0
- Android Architecture Component 1.1.0
- kotlin 1.2.30
- Retrofit 2.3.0
- moshi 1.5.0
- picasso 2.5.2

## 言語
これから開発するなら断然kotlinですね。AndroidStudio3.0からサポートすると発表されたそこそこ新しい言語です。

kotlinのいいところは**Javaと共存ができる**という点です。  
どういうことかというと、例えば3つのActivityがあったとして、うち2つのActivityはJavaで書いて、1つだけkotlinで書くといったことができます。  
またJavaで書いた関数や変数をkotlinから呼び出したりその逆でkotlinで書いた関数をJavaから呼び出すこともできます。
まずは日付変換をするようなユーティリティクラスからkotlinに変換、なんてこともできます。

Javaと互換性がありながらSwiftに近いモダンな書き方ができるので、kotlinは覚えてソンはないですね。

## アーキテクチャ
今回、目を付けたのは

  - [Android Architecture Components](https://developer.android.com/topic/libraries/architecture/index.html)
  - [Data Binding](https://developer.android.com/topic/libraries/data-binding/index.html)

ですが、どちらもGoogleから提供されているというのが特徴です。Google公式から新しいアーキテクチャの提案が出るというのは非常に面白いですね。

Androidも出てからもだいぶ時間が経ちましたし、今の時代に合わなくなってきたところをより効率的な方法で書けるようになったり標準化していけばさらに開発が楽になります。

もちろん、どちらも「使わない」という選択も取れるので、Architecture Componentsだけ使う、またはDatabindingだけを使うということもできます。

これらのアーキテクチャを使った解説を別ページで紹介します。
[最近のAndroidアーキテクチャを勉強するために、はてブアプリを開発した(アーキテクチャ編)](https://qiita.com/kuluna/items/59fbc84dd1e33c6d8d1b)

## 通信・モデル周り
ここで採用した[Retrofit](http://square.github.io/retrofit/)、[moshi](https://github.com/square/moshi)はiOSでいうAlamofireぐらいスタンダードなライブラリとなってきたようですね。昔はVolleyとかを使っていました。

Retrofitで取得したJSONデータをオブジェクトに変換する作業はmoshiが行います。Retofitとmoshiを連携するライブラリも公開されているので、API通信からJSON変換を一気に行ってくれてとても便利です。

ただRetrofit自身は別スレッドで動かさないと当然`NetworkOnMainThreadException`が出てしまいます。  
Android標準のAPIを使うとしたらAsyncTaskを、最近まではRxJavaを使って受け取る感じでしたが、今回はArchitecture Componentsの中にあるLiveDataを使ってみました。

これらのライブラリを使った解説は別のページでやろうと思います。

## View周り
Android5.0以上であれば普通に作っていてもマテリアルデザインになります。Google公式アプリのようなかっこいいUIにするための[デザインライブラリ](https://developer.android.com/training/material/design-library.html)もGoogle公式から提供されており、ただ使うだけでもイイ感じになってくれる頼もしい存在です。

今回はデザインライブラリからCoordinatorLayoutというのを使ってみることにしました。本当に文字通りイイ感じにコーディネートしてくれるライブラリです。Android標準のアドレス帳アプリ等で使われています。  
画面のスクロールに合わせてActionBarを隠したり、パララックススクロールを提供してくれます。

もう一つの[picasso](http://square.github.io/picasso/)は画像のHTTP取得からキャッシュまでを一手に受けてくれるライブラリです。キャッシュ周りのほぼすべてをライブラリで任せられるというのはすごく安心ですね。

これらのライブラリを使った解説もまた別のページでやろうと思います。

# 開発期間

- 12月下旬 漠然となんか作りたいなーと考える
- 1月上旬 正月休みを使ってなんとなく目標と作りたいアプリを考える
- 1月中～下旬 忙しくてなかなか着手できず
- 2月上旬 突然時間が取れたので2日ほどで一気に書き上げる
- 2/11 Google Play リリース

今回は目標としてことと実現のための解決手段、そしてそれが実際に勉強したかったことと見事にマッチして非常に良い勉強になったと思います。