Androidエンジニアとしてmikanに入社し、あっという間に2年が過ぎちゃいました。

はじめに

こちらはmikanのアドベントカレンダー 4日目の記事になります!

1つ前の3日目の記事は@zukkeyGASとHARMOSとSlackではじめる勤怠Botでした!エンジニア問わず誰にでも自動化の一歩を踏み出させてくれる、頑張ってやってみようかな…!!と思わせてくれるそんな記事となっております!

こんにちは!mikanでAndroidエンジニアをしている、gumiojiです! twitter.com

今年も残すこと1ヶ月を切ってしまいました….!!

約2年ほど前に僕はmikanに転職してきました。今となってはすごく懐かしいですね。

当時の気持ちを綴った入社エントリーがあるので、そもそもなんで~を知りたい方はこちらへ note.com

この記事では、入社してもう2年も経ったのか…と思ったので、大まかに自身の振り返りをしながら、mikan Androidの変化というところを紹介してみようかなと思います!

入社直後

このときはほんとにいい意味で何も整ってない状態でのスタートだったので、どういうふうにしていこうかをあれこれ考えていました。

  1. 今後入ってくる人などが安心して開発を進めていけるような状態づくり
  2. iOSとの機能差分を進めて追いつく

主にこの2点を軸に動いていました。この当時のmikan Androidはmikan iOSと1年数ヶ月分くらいは差ができていた記憶がありますw

このときの主な対応は以下の通りになります

  • GithubのPRテンプレート改善
  • DebugのためにHyperion追加
  • Library周りの依存関係を集約して管理するためにDep.ktの設置
  • 隙あらば、Kt化とButterKnifeからviewBindingに変える

GithubのPRテンプレート改善

元々mikanにはGithubのPR時のテンプレートが設置されてあったのですが、成果物のBeforeとAfterを比較する箇所がなかったので、reviewerに優しくしようということでBefore / Afterを並べるように以下の部分を追加しました

Before | After
:--:|:--:
<img src="" width="300" /> | <img src="" width="300" />

DebugのためにHyperion追加

こちらも元々mikanには簡易的なDebugMenuはあったのですが、奥深くの設定に行かないと辿り着けないような場所にあったので、いつでも呼び出せるように、その他のDebug機能も触れるように。ということでHyperionを追加しました

詳しくはこちらへ

qiita.com

Library周りの依存関係を集約して管理するためにDep.ktの設置

依存関係の設定が直に殴り書きされていたので、Dep.ktを用意したいなと思った感じです。

ちなみに今はDep.ktはversion検知するのめんどくさいのと対応しないとアップデート忘れてしまうため、Gradle v7.0から追加されたversion catalogを使用するのが良いと思います。

star-zero.medium.com

また、renovateというこういう依存関係差分を自動で検知し、アップデートをPRで投げてくれる君があるのですが、上記のversion catalogに対応しているので、相性がよさそうですね…!!(まだ移行できてない)

github.com

隙あらば、Kotlin化とButterKnifeからviewBindingに変える

ほんとに余裕があれば、Kotlin化 + ButterKnifeを使用していたらviewBindingにセットで置き換えを行ってましたw 基本の姿勢は不具合や機能追加などで画面を少しでも弄る際に関連も含めて、やるという精神でやってました!

当初はKotlin化率が大体20%くらいの状態でした(!)

今は88.6%。ほとんどJavaを見る機会がなくなりましたね…. = 改修する機会が減って残りがしぶとく生きてるという状態

2021/01~05: リデザインPJ

最初に行ったPJがメインの教材一覧, 教材詳細, ホーム画面…etc.といったメイン画面のリデザインです。色んな画面を大きくデザインを変える、これは完全新規で作ってしまった方が速いですし、チャンスだなと思い、リデザイン対象画面の使用技術をガラッと変えました。

ちなみに当時のmikan Androidの構成はほぼMVCの状態でした。要件的には複雑な設計を用いる必要性もないと判断し、当時のGoogleさんがAAC使うならこんな感じにするといいよ!という推奨の形として構築しました。

このとき導入したのは以下でした!技術採用は提案ベースで積極的に使ってきましょ!と新しく入社される方、業務委託の方々含め、話してました。

  • AAC
  • Navigation
  • Dagger Hilt
  • Coroutine
  • Coroutines Flow
  • Groupie…etc.

ほんとは既存でDagger等々を色々導入してたら、もう少し移行などがややこしかったのでしょうが完全新規導入だったため、恐ろしくスマートに導入できたので何も書けません()

強いて述べるとしたら、新しい技術は新しい画面で使っていきたいですね!!(それはそうだ)

2021/06 ~ 2022/04: DB刷新PJ

上記リデザインPJを頑張ってる中、横目でiOSがDB刷新を行っているのを見ていたのですがこのPJを超えるものは今後出てくるのだろうか。。。そのくらい大変で印象的に残っています。期間も10ヶ月ほど使いました。

→ 余裕を持って技術調査などの期間もしっかりスケジュールに組み込ませてもらいました

DB刷新って何をするの??

iOS verでのDB刷新をiOSDCの場で発表してくれた @aviciidaによるスーパー分かりやすいスライドがここにあります!

speakerdeck.com

地獄への片道切符

このDB刷新PJで実はABテストを行いました。何を言ってるかわからないと思いますが、僕にも分かりません。当時に戻れるなら本間にやるんか!? やらへんよりもやる価値のが高いんか!? と言ってあげたいですね。そしたらまだ多少は楽で済んだのではないでしょうか….。 今戻るなら、ABテストはしないと思います…w

iOS先行で実施した際はABをやってなかったのですが、結果的にDB刷新はもうクローズしてよいのだろうか…..??? 何を見てそう判断しよう…??? 分からないから画面の表示速度をログとして飛ばすようにし、そこから分析で判断するようになっていたのがきっかけです。Androidでも同じようにデータ取得までの速度という観点でそれにKPIを紐付けてみるようにしてました。結果としては良くなってたので、すぐに判断できたのはABやっててよかったなとは思ってます。

こういった超絶大規模な変更などはABをやっても良いとは思うのですが、大前提として戻すことはない片道切符だったので、仮に数値影響が出たとしてもそこから改善をまわしていくという判断にしてもよかったのかなと思ってます。それでもこんな機会は二度あるかないかレベルなので、興味が止まらないわけですね。やってしまいましたね!!!!!

設計のお話

先行したiOSからヒアリングした上で実施したため、Androidでは結果的に以下の意見を踏まえ、実験的な構成にしました。

「firestoreのcache、ハンドルできなくない?? こっち側でオフライン対応を持ってしまえば、今後remoteDataSource何になってもオフライン利用できるんじゃないかなと。ついでに通信節約、パフォーマンス向上にもならないかな??」

こうした話から、Androidではキャッシュ層としてRoom(SQLite)を利用しています。一度Roomに問い合わせ、なかったらfirestoreに問い合わせ、Roomに保持するというようなよくある形です。

そのため、mikan Androidではfirestoreのcache機能をoffにしてます。なんでfirestore使ってんの??というツッコミはお控えください!

何が大変だった?

一番はやっぱり今までコアなデータをLocalDataとして持っていたRealmの引き剥がしでした。引き剥がしさえしてしまえば、後は楽だったのですが1つ剥がせば10箇所くらいから悲鳴があがるあがる…。そんな印象でしたねw

それにユーザーさんの大事な今までのデータがうっかりミスなどで吹っ飛んだり、変な間違ったデータになったりしないか(不整合と呼んでました)、神経質になりながら作業してるのが辛かったですね。PJを始める半年前、僕が入社する辺りにダブルライトPJというLocalDataにも移行先のfirestoreにも同じ内容を書き込むという手順を踏んでいたのですが、実装を通じてテストしていく中でLocalだけに書き込まれるパターン、Remoteだけに書き込まれるパターン..etc.が出てくる&出てくることで、これはあかん…。ってなったためです。

それに追い打ちをかけるのがABテストによる、確認の多さです。本来1パターンで済むものを何倍にも膨れ上がらしていたので、出来たてホヤホヤのQAチームとAndroidチームは悲鳴をあげていましたw

もちろんリリースまでの開発も大変だったのですが、リリース後も大変でした…。

リリース後は速度が遅い問題と向き合う

大前提としてABの結果からも全体的なパフォーマンスはよくなってはいたのですが、限られた環境下でパフォーマンス面にかなり問題があり、一部のユーザーさんには恐ろしく学習体験を低下させているという状況になり、お問い合わせがかなり来て大変でした。

→ リリース後すぐに速度改善PJが立ち上げるほどでした。

全員がそうなっているというわけではないのが大変ポイントで、原因はブラックボックスな状態からスタートしました。様々な検証や仮説を立てるためにログをたくさん仕込むなどを主に行い、パフォーマンス改善に取り組みました。

主な大きな原因は以下でした

  • Localからデータ取得してくる想定なのにRemoteにアクセスし続けている
  • 最新情報をfetchしてくる際の効率が悪い

1つはネットワーク接続状態を常に監視して、状態を変えていたのですが期待しない挙動をするときがあった。もう1つは別端末などで更新があったり、マスターデータといった書籍のデータを新しく保つために起動時にfetchしているのですが、それが遅すぎたというのがありました。

まだまだベストとは言えない

当時と比べるとかなりパフォーマンスは良くなったのですが、かなり快適か?といわれるとまだまだ改善ポイントはあると思っています。現在も速度改善は隙間時間を活用して、取り組んでいます。

とはいえ隙間時間で改善できる範囲はしれており、これ以上高速にするには現状の構成から大きく変更する必要があると思っており、今は現状の形で運用を続けています。

まとめ

  • 結果的にはRoomを合間に挟んでみる方式をやってよかったなとは思ってます
  • こういったデータ移行作業に立ち会える機会は同じ会社に居続けても中々ないことだと思いますので、いい経験になった
  • ほんとに繰り返しになりますが、アプリ全体に変更が加わるようなABテストをやるなら明確な目的をもって行いましょう(戒め)
  • パフォーマンス大事

2021/10 ~ 11: 突然のBilling Libのupdate期限に追われる

これはほんとに盲点で、課金系をあまり触ってこなかったという言い訳もするのですが上記のDB刷新を実装してる際にGoogle Playから、「お前らそろそろBilling Libraryを新しくしろよw」という通知が来てしまって、冷や汗でした。

なんでアップデート?

Google Playの課金ライブラリである、Billing Libraryは毎年Google IOのタイミングで、メジャーバージョンが上がる傾向があるのですが、新しいバージョンがリリースされてから、2年間がサポート期間となっており、移行期間に2年ほどの猶予が与えられます。

mikan Androidの当時はBilling Library? ナニソレオイシイノ? という状態で、BL2が宣言だけされてはいるものの、課金アクセスはAIDLが使用されてました…OH

少なくともBL3に上げないといけない!でも来年すぐにまたBL4に上げないといけない!という状態になるので、余裕を持つために最新のBL4にアップデートするプチPJを差し込みました。

しゃりふ神タイミング良すぎる

Android界隈で課金といえば〜?

しゃりふ氏〜!

twitter.com

はい。このときmikanでは最高のタイミングでしゃりふさんを業務委託としてお迎えしてましたので、超絶感謝の気持ちを込めて対応をしていただきました(ほんとにありがとうございます)

クライアント管理からバックエンドに移行

AIDL → BL4にぶっ飛んだわけなのですが、完全クライアント完結の課金管理をしていたため、このタイミングでDB刷新後にバックエンドに寄せるための準備対応を入れました。

  • 購入後の承認はバックエンドのAPI
  • 承認完了後のユーザーデータと課金情報を紐づけれるように裏側でレシート保存だけしておく

いつでも移行やステータスを引き継げるようにこのような状態のみに削って対応を済ませました。

削って準備だけに留めたのは、DB刷新を達成することが最優先だったのと、DB刷新後じゃないと好きなアカウントにアクセスしたりすることができないため、課金ステータスを引き継いだりさせるということができなかったため

アップデートはお早めに

今回のBilling Libraryだけに限らず、色んなLibraryやOSといったものは即座にアップデートすることを心がけましょう…!!!

mikanだったから即座に差し込み対応ができただけで、組織によっては差し込めないときもあると思いますので、お早めに。

2022/04 ~ 06: アカウント管理

一番大変なDB刷新PJが無事にリリースされ、本来のDB刷新の目的、どのPFからでもデータにアクセスできるように。を達成するためにアカウント機能を用意しました。

この時から、るんるん気分で実装をしていました。もうDB刷新を超えるものなんていないからねって。あれに比べたら~を口癖にしてた気がしますw

mikanではfirebaseを採用してるため、firebase authを利用し、以下のプロバイダで用意しました

  • Twitter
  • Google
  • メールアドレス
  • Custom Token = mikan for school

mikanではtoB向けの事業、mikan for schoolというのをやっており、通常のアカウント機能 + こちらの生徒さん向けのアカウント機能も同時に作成していました。

forschool.mikan.link

余談: Apple認証はあまり需要を感じなかったので用意していなかったのですが、皆さんはどうでしょう?? あったほうがよい!とかあったりしますか??

初めましてJetpack Compose

このタイミングでめでたくComposeデビューを果たしました。

Jetpack ComposeはAndroidが提供してるUI宣言型のUIツールキットです。

iOSでいうなら、SwiftUIですね。

developer.android.com

採用しない理由はなかったので、この頃からmikan Androidでは新規で作成するUIに関してはComposeを使用すること。業務委託の方にはちょこちょこ既存の画面をComposeに移行するタスクなどをお願いするようにしていました。

結論、Compose最高ですね!!!!!!!

ほんとに楽です。もうXMLは読めません。読みません。よろしくお願いします!!

これでめでたく、firestore上のデータにいつでもアカウント連携・ログインすることができるようになりました!さあ、mikan Androidの基盤完成まであと一歩です….!!!

2022/07 ~ 11: PRO PLUS対応

今までmikanは英単語アプリとして英単語の学習などを効率よくさせるために機能などを提供していたのですが、これからは英語アプリとして進化していくために英単語以外も1機能として提供していくことをiOS先行で始めてました。

こうした新たなリッチな機能の提供を既存の課金プランのmikan PROではなく、より上位の課金プランとしてPRO PLUSを用意することになりました。

PRO PLUSのことをもっと知りたい方はこちら!! mikantechnology.notion.site

この時点でiOSもPRO PLUSをリリースし、落ち着いたのが6月中旬でした。

皆さん僕が最初に言ってたことを覚えてますでしょうか!?!?

| この当時のmikan Androidはmikan iOSと1年数ヶ月分くらいは差ができていた記憶がありますw

そうなんです、もうiOSの背中がほぼ見えてきました!!!!

課金つらい….色々つらい….

Androidで課金実装をちゃんとしたのは今回が初めてでしたが、ほんとに考えることが多いんだなと思わされました。単なる上位プランの導入、アップグレード、ダウングレードのみだったらまだよかったのですが、先程あげたように課金ステータスをバックエンドで管理することが完了してません!

なのでこのPJでは僕が兼PMっぽいこともしていたこともあり、上位プランを導入 + 課金ステータスをバックエンドに寄せるという実質2つの対応が含まれたものになっていたため、スコープを細かく切って、段階的に開発、QA、リリースをするように進めてました。

同じことは繰り返さないということで、すぐさまBilling Libraryをv5にアップデートしたのはいいのですが、リリースしたてで情報が全然ない故に試行錯誤で検証することも多かったのがツラミポイントでした。この辺りの細かな話は18日のアドカレ記事で1本使って話そうかなと思っていますので、ぜひお楽しみにです!

まとめ

  • 課金って考慮することたくさんで大変だねb
  • テスト環境を用意しても確認が大変だねb
  • リリースほやほやのバージョンは全然情報がなくて大変だねb

宣伝

ありがたいことに11月中旬にリリース完了し、何も問題なく今を過ごしています!ほんとに何もなさすぎて怖いくらいです!何も起きないくらいmikanのQAチームは優秀です!

さて、今回僕が担当していたPRO PLUSでブロッキングをくらっていたPRO PLUSの機能や、それに付随したたくさんの教材たちが一気に開放されました!ぜひ一度iOSでもAndroidでも構いませんので、手にとって触ってもらえたらなと思います。よろしくお願いします!

現在進行形

そしてこの記事を書いている今に至るわけですが、仕事に夢中になっていたら2年が過ぎちゃいました…。ほんとにあっという間の2年でした。

mikan Androidの基盤はLegacyな部分もまだ残っていたりはしますが、2年前の自分が思っていたくらいには整ったと思っています。これから先はユーザーさんにより価値のあるプロダクトとしていい体験を届けれるように頑張っていこうと思います!

mikan Androidはこれからも常にモダンな形を模索しながら、チャレンジングに楽しみながらアップデートさせていこうと思います!

さいごに

いかがだったでしょうか? 最後までお読みいただき、ありがとうございます!

あまり役に立つことは今回書いていないのですが、誰かのためになればいいかなと思ってますw

そんなmikanでは最高の英語アプリを共に作っていける仲間を常に探しております!(特にデザイナー…!!)

お気軽にTwitterでも下記のHERP経由でもご連絡ください。主はSplatoonが大好きなのでSplatoon面談もWelcomeです!

herp.careers

明日は@gamiの記事です!お楽しみに!