2019年1月における note Androidアプリの開発現場

2019年1月における note Androidアプリの開発現場について、ざっと書いてみます。
「あれについて聞きたい」、「これについて聞きたい」など質問・疑問などあれば、ぜひ記事にコメントしていただけると嬉しいです。

書いてる内容などは違いますが、影響を受けたのは以下の記事です。

note Androidアプリはこちらです。

開発体制

Androidエンジニア 1名(私)
デザイナー 1名(iOSアプリのデザイナーも含めると2名)
バックエンドエンジニア 1名(CTO)
QA 1名

どんな改善をするかを決め、ある程度実装して、そろそろリリースするかなーと思ったらQAしてもらい、QA完了したらリリース、という流れです。

どんな改善・施策を行うかは、アプリエンジニアが率先して考えて決めています。主に改善・施策を行うことで、アプリでの体験が向上しそうなものを優先的に実装しています。実装工数を意識することも大事ですが、工数がかかっても体験が向上させることを優先しています。

開発言語

JavaとKotlinを使っています。
noteのアプリは2014年から開発が始まっているため、多くのコードがJavaで書かれていま(私が開発に関わり始めたのは、2018年7月から)。
私がJavaで書いたほうが開発効率がいいので、現在も基本的にはJavaで書いています。
簡単な実装には積極的にKotlinを使っていき、徐々にKotlinのコードも増やしていく予定です。

以下はnote AndroidアプリのGithub Repositoryで見た言語比率です。

minSdkVersion

21です(Android 5 以上サポート)。
2018年12月まではminSdkVersion 15で、Android 4.x もサポートしていましたが、 Android 4.xでアプリを使用してる人が減ってきたなどの理由でminSdkVersionを21に上げました。

minSdkVersionを21に上げる思いなどはちょっと前にTwitterで書いたりしました。

targetSdkVersion

28です。Android Pをターゲットに開発しています。
targetSdkVersionは積極的に上げていく方針で開発してます。
そこら辺の理由などについては、過去にnote engineer meetup #1でお話したので、以下の資料を参照してください。


----- 🍭-----


ここからは実装をする上でよく使ってるライブラリなどについて書きます。

DataBinding

レイアウトはできるかぎりDataBindingを使うようにしています。
ObservableFieldやTwo-way data bindingは行っていません。
あくまでfindViewByIdしなくてもViewにアクセスできるようにすることや、Viewへのデータ反映を楽にすることを目的で使ってます。

OkHttp + Retrofit

Http ClientにはOkHttp + Retrofitを使っています。
Converter.Factoryなどを使ってレスポンスをよしなにやってたりしますが、特殊な使い方などはあまりせず、普通に使ってます。

Moshi

JSON ライブラリはMoshiを使っています。
まだ 1.5.0を使っているのと、Kotlinのコードが少ないのでCodegenの恩恵は受けてないです...。

RxJava 2.x

最近だとCoroutinesの方がいいのかな?って思うこともありますが、使い慣れたものの方が躓くことが少ないのでRxJavaを使ってます。
とはいえ、まだ導入したばかりなのでどう使っていこうかを考えてる最中です。

RxRelay

画面をまたいだステータス更新などにRxRelayを使ってます。
note Androidアプリ開発の前任者の方はBroadcastReceiverを使っていましたが、実装のコード量が多くなりがちなので、staticなRxRelayを使うように最近はしてます(賛否はありそうですが...)。
以下のようなクラスがあり、これをRxJavaを使うのと同じように使っています。

public class GlobalRelay {
    public static final PublishRelay<XXX> notifyDeleteNote = PublishRelay.create();
    public static final PublishRelay<XXX> notifyLikeNote = PublishRelay.create();
    public static final PublishRelay<XXX> notifyUnlikeNote = PublishRelay.create();
}

Picasso

画像ダウンロードライブラリにはPicasso バージョン 2.71828を使っています。普通に問題なく使えてます。Picasso 3に期待したいところ。

Lightweight-Stream-API

JavaでOptionalとStreamを使用するために使ってます。
過去にContributeもしてるライブラリなので気に入ってます。

Icepick

instance state周りはこのライブラリに任せてます。

AndroidAnnotations

このライブラリの機能はできるかぎり使わないようにコードを書き換え、現在ではSharedPreferences周りだけに使われています。

今後SharedPreferences周りもKVS Schemaとかに変えようかと思ってます。


----- 🍭-----


ここからは実装以外の観点で使っているものなどについて書きます。

Firebase Analytics + BigQuery + Redash

アナリティクスにはFirebase Analyticsを使い、Firebase Analyticsの情報をBigQueryに流しています。
BigQueryにたまったデータをRedashを使って集計・分析しています。

Firebase Test Lab

リリース前のQA時にFirebase Test LabのRobo Testを活用しています。
導入が簡単で価格も安いのでオススメです。
Firebase Test LabのRobo Testの概要については、去年 勉強会で発表した以下の資料を参照してください。

Crashlytics(Firebase Crashlytics)

クラッシュレポートはCrashlyticsを使ってます。

CircleCI + Danger

CIはCircleCIを使ってます。CircleCI上でDangerを動かして、Android Lintの実行やPull Requestのチェックなどを行っています。Danger便利です。


----- 🍭-----

導入してないものなど

Android JetpackのViewModel、LiveDataなどは現状は一切使ってません。
AndroidX移行もまだ行ってないです。
私の勉強不足が主な理由で導入・移行などを行ってない状態です。勉強します...。まだ導入して自分なりに納得感がある実装が見つけられていません。
これからもっと色んな方々のコードを読んで参考にします。

設計は考え中の段階です。現状ではActivityやFragmentにわりとべた書きなことが多いです。
下手なものをいきなり導入して失敗しないためにも、noteアプリの仕様・性質の理解をした上で、どういう設計がうまくはまりそうなのかを見極めてからやっていく予定です。
noteのプロダクトの状況も加味した上で、設計を無理に急ぐ段階ではないと考えてます(アプリの体験向上を優先するということもあり)。

DIも設計と関わる部分があると思っているので、まだ導入はしてません。


まとめ

一人でアプリ開発をしているとどんどん新しい仕組みを導入して、いい感じの開発にすることも可能だとは思います。私もそういうのに憧れがあります。しかし、新しいものを学び、導入してうまく運用するコストを払うことが難しい場合もあります。
その場合、ちょっと古くても手慣れたやり方でやっていくのもありだと思います。現状のnote Androidアプリはそんな感じです。

もちろんずっと古いままでやっていくのかというとそうではないです。
個人的にはタイミングを大事にしたいと思ってます。
「今 優先してやるべきことはなにか?」を常に考えた上で、判断し、新しいものも徐々に導入したりしていきたいと考えてます。

これを読んでいるあたながもしかしたらnote Androidアプリエンジニアの2人目になるかもしれません。
そうなったときは、ぜひ一緒に色々考え、議論しながらいいアプリ、いい開発をしていきたいと思い、今日もアプリを開発しています。

サポートしてもらうことで、キンパツは大好物のミスドが食べられます!よろしくお願いします!