Pairs JapanにおけるActionLogの実装に関する補足
どうもこんにちは、Androidエンジニアのzukkeyです!
先日行われたMeet Upの際に概念だけの説明をして、もう少し詳しく知りたいとのことがありましたので、この場をお借りして補足説明を行っていきます。
発表の際にも触れましたが、現在Pairs Japanでは自前のログ計測の仕組みを「ActionLog」と定義しており、Evernote製のライブラリandroid-jobを用いて実装しています。
今回はandroid-jobの構成とそれを用いてどのようにActionLogを実現しているのかについて発表の中で触れたことについてコードレベルで説明します。
当日のスライドは下記になります。今回はこのスライドの補足になります。
android-jobの構成
最初にandroid-jobの構成について軽く触れておきます。
android-jobの構成は次の通りになっております。
JobRequestのBuilderクラスでRequestを生成し、JobCreatorにスケジュール要求を行います。
JobCreatorでは、自分たちで定義した各Jobを作成し、JobManagerにJobが順次キューイングされていき、各Jobを実行するという構成になっております。
PairsにおけるActionLogの構成
設計当初はBaseActivityとBaseFragmentのonResumeにログ送信の仕組みを実装しておりましたが、複数のFragmentがある場合では特定の画面だけを取りたいのに全ての画面のログが出てしまう問題にぶつかりました。
例えば、次のような場合です。
Activityの上に複数のFragmentが存在している場合に、一番上の子のFragmentのログを取りたい時、onResumeにログ送信の処理を持たせてしまうと次のスライドのように全部のログが出てしまうようになりました。
そこで、私たちはこの問題に対処するべく次のように対応いたしました。
まず、次の3つの機能を持つインターフェースを定義します。
- どの画面であるかの情報を取得する機能
getScreenEvent()
- ログ送信の機能
sendScreenEvent()
- ログを送信するかどうかを担う機能
sendScreenEventIfTrackable()
実際のコードは次のようになります。
ScreenEventParameterで取りたいログの項目を設定します。
このTrackableScreenTypeのインターフェースをBaseActivityとBaseFragmentに実装させます。
今回は、BaseFragmentをもとに説明していきます。
getScreenEvent()では、デフォルトでは何もせず各画面にて必要な情報を取得するようにします。
sendScreenEvent()では、getScreenEvent()で得た情報を元にJobCreatorで生成したJobをJobManagerにキューイングしていき、一定のログが溜まった時点でログを送信しています。
sendScreenEventIfTrackable()は、Baseでは何もしないで必要に応じてsendScreenEvent()を呼びます。
ここからは具体的にスライドに触れながら説明していきます。
スライド中にあった複数のFragmentが重なっている下記のような場合
親のフラグメントは、SeparatedMessageFragment.javaです。
ここでは親のFragmentのログを取得したくないので、子のFragmentに処理を任せるようにします。
まずは、次の通りに子のFragmentがあるか確認します。
子のFragmentがない場合は早期リターンするようにし、子のFragmentがある場合は、子のFragmentのsendScreenEventIfTrackable()に処理を流します。
次に、子のFragmentにてBaseFragmentのsendScreenEvent()を呼びます。
イメージとしては次のスライドになります。
実際のコードは以下になります。
これで、ターゲットとしている画面にてログを送信する処理を実現することができました。
スライドの補足については以上になります。
おわりに
android-jobは公式でWorkManagerが出たため、サポートが終わってしまうようですが、今回の仕組みに関しましてはライブラリが変わったとしても使えると思いますので、ログ計測の実装で悩んでいらっしゃる方に少しでもお役に立てたら幸いです。
また、エウレカでは一緒にプロダクトを成長させていく仲間を随時募集しております!
少しでも興味を持っていただけましたら、下記Wantedlyからご応募をよろしくお願いいたします!