Android版Misocaのマルチモジュール対応

こんにちは!アバター化して可愛くなったこまたつです!!
この前オフィスに来たお客さんに「声はオッサン」て言われたのですが、最近ボイチェンカラオケにハマっていて声も可愛くなってきました。

みなさんのプロダクトはマルチモジュール対応してますか?

InstantAppやDynamicDeliveryなど、新たに追加される機能はマルチモジュール前提のものも多く、強めの圧を感じるようになってきましたね。
今回はMisocaのAndroidアプリでどんな感じにマルチモジュールの対応を行っているかを共有します。
ライブラリ以外のマルチモジュール初挑戦だったので理解の浅い部分が多いのですが、みなさんからの優しいつっこみお待ちしております。

Misocaは請求書作成をメインとしたサービスですが、請求書以外にも業務フローに合わせて見積書や納品書を作成できます。
Androidアプリでは先日のv3.0リリースでこの3種類すべてに対応しました。
文書はそれぞれ微妙に異なっていて、たとえば郵送ができるのは請求書だけという作りになっています。
そこで、次のようなモジュール構成を考えました。

f:id:komatatsu:20181019144328p:plain

これを考えたときには実はまだ見積書と納品書の機能は存在しておらず、ひとつのモジュールに請求書とログインなどの機能が入っている状態でした。
先行するiOS版に比べて機能的に貧弱ということもあり、ひとまず次の形で見積・納品書の機能を追加することにし、請求書の分離作業は後回しにしました。

f:id:komatatsu:20181019144921p:plain

これらの機能は新規に追加されるコードだったので穏便に分割することができました。
それと同時に新たな問題点が見つかりました。
アプリには取引先に紐づく各文書をタブで切り替えて見られる画面があります。

f:id:komatatsu:20181019144423p:plain

この画面があるせいで、処理を完全に分割するのが難しくなってしまいました。
この画面はbaseモジュールに入っていますが、baseを見積書や納品書のモジュールが参照しているため、逆向きの参照が入れられません。
またモジュールをまたぐ画面遷移とモジュール内の画面遷移でIntentの取得方法が変わり複雑度があがってしまいました。
コードを書くときはなるべくモジュールを気にせずに書ける様にしたいです。
これらはまだ解決方法を模索中ですが、ほかにも小さな問題をいくつか解決しました。

BuildFlavorsで設定したapplicationIdがBuildConfigから取れない

取れない(つらい)
仕方ないので activity.packageName を使うように書き換えました

AndroidManifestを分割しなかったのでテストがこける

全部appに書かれたままほっといたらInstrumentation Testがコケるようになってました。
モジュールごとに適切に分割することで解決しました。

proguardのminifyをかけると動かなくなる

packageは変えてないのですがentity類をbase moduleに移動したら、引数なしのコンストラクタが無いエラーが出るようになってしまいました。
entityは基本的にkotlin data classを使っているのですが、今まではGsonがUnsafeを使って処理していたものがminifyによってうまく動かなくなったみたいです。
一次対応としてproguardのルールを変更しましたが、ちゃんと引数なしのコンストラクタを作ってあげたほうが良さそうです。

そんな感じで、まだまだいろいろ問題が出てきそうな雰囲気を感じます。
モジュールの分け方も文書ごとに分けるのではなくもっと適切な分割方法があるのでは?などとissueを立てて議論しています。
アプリを成長させて行くためにも開発しやすい状態を作るのが重要だと思います。
ただ分割しただけでは何も始まらないので、これから試行錯誤を繰り返しつつ少しずつ馴染んで行きたいと思います。

採用

Misocaに興味のある方はぜひフォローしてくださいね