Android版Conobieの改善 〜旬なLibraryを添えて〜

『[LITALICO Advent Calendar 2016](http://qiita.com/advent-calendar/2016/litalico)』10日目の記事となります。

はじめまして！[株式会社LITALICO](http://litalico.co.jp/)で技術顧問をしている @higassiy です。LITALICOでは主に[Android版Conobie](https://play.google.com/store/apps/details?id=jp.conobie.conobieandroid&hl=ja)の開発全般のお手伝いをしています。
今回は私がお手伝いをさせていただくことになってから、どのような改善を行ったかを項目別に紹介したいと思います。

## はじめに
今年の7月上旬にローンチされたAndroid版Conobieですが、このときのバージョン（以下、初期バージョン）は私とは関係がない別の協力会社と一緒に開発を行ったそうです。
ローンチ後の7月中旬に、前職の上司であり、LITALICOのCTOである @takish さんからアプリのクオリティについて相談されたのをきっかけに技術顧問を引き受けることになりました。

現在はLITALICOのエンジニア2名と私とで開発を行っていますが、私の主なミッションは『__アプリを良いものにする__』と『__LITALICOのAndroid開発レベルを引き上げる__』という2点があります。そのため、ただ単に自分が好きな技術やLibraryだけを選定するのではなく、世の中で広く知られている王道な作り方を踏襲しつつ、ちょこっと冒険をしながら、チームでの開発力が上がる技術選定をすることを心がけています。

以上のことを頭に入れて読んでもらえると非常に嬉しいです。

## Java vs Kotlin
昨今のAndroid開発においてはJava以外に __Kotlin__ で書くという選択肢もかなりメジャーになってきました。
Conobieでは初期バージョンがJavaで書かれていたこともあり現時点では引き継いでJavaで実装をしています。また、今のところはJavaの方がインターネットでの情報量が多いため慣れていない状態でAndroidアプリを作るにはJavaの方が適していると思っています。

ただしテストコードに関してはKotlinで書く環境を整えました。プロダクト本体に直接影響がないところで、Javaより簡潔に書けて、かつ言語に慣れることができるため、Kotlin導入に踏み切れない場合はテストコードから導入してみるのはありだと思います。
Conobieのプロダクト本体に関しても現時点ではJavaですが、今後Kotlinに置き換える可能性は十分あります。

__参考リンク__

- [Kotlin](https://kotlinlang.org/)
- [Android開発を受注したからKotlinをガッツリ使ってみたら最高だった](http://qiita.com/omochimetaru/items/98e015b0b694dd97f323)
- [Kotlinでテストコードを書く](https://shoma2da.net/2016/07/03/kotlin-test-code/)

## アーキテクチャ
初期バージョンは特にアーキテクチャを意識することなく、Activityにモリモリ実装している状態でした。
特に問題を抱えていないアプリであればActivityにモリモリ実装していくことは全く問題ないと思っていますが、開発人数が増えた場合の効率、アプリ全体のコードの統一、テストコードの書きやすさを意識するならアーキテクチャは導入した方が良いと思います。
実はまだConobieでもアーキテクチャの導入には至っていないのですが、RxJavaを利用した __MVP（Model-View–Presenter）__ を導入しようと基盤を設計している段階です。Googleが公開しているサンプルコードの実装がお気に入りなのでかなり参考にしながら進めています。

__参考リンク__

- [Googleが公開しているMVPのサンプルコード](https://github.com/googlesamples/android-architecture/tree/todo-mvp-rxjava)
- [AndroidではMVCよりMVPの方がいいかもしれない](http://konifar.hatenablog.com/entry/2015/04/17/010606)

## Material Desiginに沿ったUIパーツ
最近は、Android Design Support Libraryがかなり充実してきているため、Material Designに沿ったUIを実装する際にサードパーティ製のLibraryを使用することはほとんどなくなりました。
しかし、初期バージョンではUI部分でサードパーティ製のLibraryをいくつか使っていたため置き換えを行いました。Library特有の機能をヘビーに使用していない限りは置き換え可能だと思うので、もしも同じような状況であれば置き換えることをオススメします。

| 使用していたLibrary | 置き換えた仕組み |
|:-----------|:-----------|
| [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip)|        [TabLayout](https://developer.android.com/reference/android/support/design/widget/TabLayout.html)|
|[SmoothProgressBar](https://github.com/castorflex/SmoothProgressBar)|[ProgressBar](https://developer.android.com/reference/android/widget/ProgressBar.html)|
|[ExpandableHeightListView](https://github.com/paolorotolo/ExpandableHeightListView)|[RecyclerView](https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html)|
|[ActionSheet](https://github.com/baoyongzhang/android-ActionSheet)|[BottomSheetDialogFragment](https://developer.android.com/reference/android/support/design/widget/BottomSheetDialogFragment.html)|

特にActionSheetのような他OSのガイドラインをAndroidに持ち込んでいるLibraryは、最悪なUIが出来上がってしまうため、すぐにも駆逐することをオススメします。

__参考リンク__

- [Material Desiginのガイドライン](https://material.google.com/)

## HTTP通信
初期バージョンのHTTP通信は、Apache HTTP ClientとVolleyとOkHttpを併用している不思議な構成になっていました。
そのため、ここは迷わずに __Retrofit（+OkHttp +GSON） + RxJava + RxAndroid__ を使った仕組み一本に置き換えることを決めました。AndroidのHTTP通信に関しては、この組み合わせがデファクトスタンダードになりつつありますし、私が関わっている他のプロダクトでも現在はすべてこの組み合わせでHTTP通信しています。

ただ、この組み合わせはThreadを全く意識させない便利すぎる仕組みになっているため、使用する前に従来のAsyncTaskを使用した通信を一度さらっと学んでおくと理解とありがたみが倍になります。

__参考リンク__

- [Retrofit](https://github.com/square/retrofit)
- [RxJava](https://github.com/ReactiveX/RxJava)
- [RxAndroid](https://github.com/ReactiveX/RxAndroid)
- [OkHTTP + Retrofit + RxAndroid で REST クライアントを実装する](http://dev.classmethod.jp/smartphone/android/okhttp-retrofit-rxandroid/)

## ImageLoader
初期バージョンのImageLoaderはPicassoを使用していましたが、現時点でConobieは日本のみでしか展開していないために __Glide__ を使うように修正しました。
日本のように通信環境が良く、高いスペックの端末が出回っている場合はカスタマイズなしで使えるGlideの方がオススメです。

__参考リンク__

- [Picasso](https://github.com/square/picasso)
- [Glide](https://github.com/bumptech/glide)
- [PicassoとGlideのどちらを使うべきか？](http://qiita.com/rejasupotaro/items/ead90beaeaa2a6eace35)

## その他、コードがスッキリ書ける便利なLibrary
その他、コードがスッキリ書ける便利なLibraryをいくつか導入しました。

### [RetroLambda](https://github.com/orfjackal/retrolambda)
言わずと知れたラムダ式とメソッド参照をJava7の環境でも使えるようにしたバックポートライブラリです。
Listenerを実装するとき、これがあるとないとでは全く違ってくるので非常にオススメです。

ただし、Jackコンパイラを使うようにすれば不要になるLibraryなので近いうちに削除されると思います。

### [PermissionsDispatcher](https://github.com/hotchemi/PermissionsDispatcher)
Android 6.0で導入されたRuntime Permission対応を楽にしてくれるLibraryです。Annotation Processingを使って作られているため、指定のAnnotationを付けるだけで簡単に導入することができます。
プレーンな状態で実装すればわかるのですが、Runtime Permission対応は地味にめんどくさいのでこのLibraryは非常に役立ちます。

### [OnActivityResult](https://github.com/vanniktech/OnActivityResult)
onActivityResultの処理をAnnotationでできてしまうLibraryです。こちらもAnnotation Processingを使って作られているものになりますが、煩わしかったonActivityResultの実装から少し解放されるので気に入っているLibraryになります。

## 現在のRxJavaの使い所
RxJavaに限らずReactiveXは学習コストが非常に高い（私も未だにわからないことだらけ）ため、キャッチアップしやすいように徐々に導入を進めています。
現在はHTTP通信周りとEventBusにのみに絞っていますが、今後アーキテクチャ周りやUIイベントのハンドリングなど必要になってきたと思うタイミングで都度使用を拡大していこうと思っています。

## さいごに
今回はAndroid版Conobieをどのように改善しているかを紹介しました。まだ一部導入できていないものもありますが、改善を進めながらアプリとして少しずつ良くなってきているのを感じています。
今後もAndroid周りの技術トレンドを追いつつ、Conobieに合うスタイルを見つけていければと思います。
まだまだ発展途上のアプリですが、きっと2017年はベストアプリをいただけるほど躍進するでしょう！

明日の[LITALICO Advent Calendar 2016](http://qiita.com/advent-calendar/2016/litalico)は @tomotomospot さんによる『プログラミングを子供に教えていて感じたちょっとした時代ギャップ』についてです。お楽しみに♪