CodeIQ MAGAZINECodeIQ MAGAZINE

ヤフーがAndroidアプリに関する技術や開発事例を共有する「CAMPFIRE Android」を開催

2017.06.07 Category:勉強会・イベント Tag: , ,

  • 15
  • このエントリーをはてなブックマークに追加

ヤフーのAndroidアプリ開発に携わっているエンジニアが登壇し、現場での取り組みやTipsを紹介するMeetupイベント「CAMPFIRE Android #1」が4月19日に開催された。エンジニアが持つ知見や、アプリ設計論からIoTまで多岐にわたったイベントの概要を紹介する。 by 馬場美由紀 (CodeIQ中の人)

Yahoo!知恵袋をRxJavaでフルリニューアル

ヤフーのAndroidにおける技術情報を共有するMeetup「CAMPFIRE Android #1」が、4月19日にヤフーのコワーキングスペース「LODGE」で開催された。

「Yahoo! Japanでの取り組みや開発のコツを知ることができる」「Androidアプリ開発の情報をアップデートできる」ことから、定員100人を超える人たちが集まった。

まずはドリンクで乾杯。ラフな雰囲気で始まった

最初のセッションを行ったのは、Yahoo!知恵袋を担当している(取材時)中里直人氏。タイトルは「RxJavaを1年使って見えてきたこと」。

Yahoo!知恵袋は1年前にフルリニューアルしている。リニューアルに取りかかったのは2015年11月。その際に導入したのが、RxJava(RxJava1)だ。アプリの基本構成は次の通り。

RxJavaを使ってよかったのは「非同期処理が簡単になったことと、複数箇所で最新情報を表示できるようになったこと」。

まずは非同期処理が簡単にした方法について。API Requestについては、通信処理をRxでラップ。「OSSを使えば勝手にやってくれることも多いので」と中里氏は説明する。

またModelについてはレスポンスクラスをデータクラスに変換することで、適宜キャッシュを返したりするようにした。Activityについては、データを受け取って表示更新処理などを行い、エラー時の挙動も書いた。

続いて複数箇所で最新の情報を表示するために、ModelにBehaviorSubjectを保持し、観測用の関数を用意した。またdoOnTerminate() for Singleについては、成功しても失敗しても実行する処理を書いた(ObserbleにあるものをSingleに実装)。

そしてProgressDialogを簡単に表示するように実装、さらには二重リクエストを防止するようにした。

中里氏いわく「こうしておけば良かった」ことは、まずは通信要求と通信状態を分けること。画面回転などをしたときに、通信状態が引き継げなくなるからだ。

次にunsubscribeする場所をよく考えること。第三にストリームに流す値をimmutableにすること。第四にストリームにnullを流さないこと。なぜならRxJava2に移行できない可能性があるからである。

第五にListの更新方法を統一するなど、Listっぽいものの扱いに注意すること。第六にRecyclerViewを積極的に使うこと。要素の挿入や内容の変更が非常に大変になってしまったからだという。

中里氏は最後に、今後はRxJava2に移行を予定しており、またKotlin化も進めたいと語った。

大規模アプリケーションを支える設計とは?

続いて登壇したのは、Yahoo!JAPANアプリのプロジェクトマネージャーであり開発チームリーダーとしてメンバーをけん引している牧竜也氏。

セッションタイトルは「大規模アプリケーションを支える設計」。Yahoo!JAPANアプリで設計を見直すプロジェクトについて紹介した。

アプリ開発の初期パターンとしてよく活用されているのが、Smart UI Pattern。これはビジネスロジックをUIに実装するパターン。一般的にアンチパターンとして認知されており、シンプルな機能やスピード重視では採用されがちだが、「大規模なアプリケーションだと破綻する」と牧氏は言う。

ActivityやFragmentにビジネスロジックが集中し、肥大化するからだ。

そこで破綻しにくいアプリケーションを実現するために、ビジネスロジックをUIから切り離すことにした。

こうすることで、ActivityやFragmentが肥大化せず、ビジネスロジックのユニットテストが書きやすくなる。さらにUI・ビジネスロジックの変更がお互いに影響し合わず独立して行えるようになるからだ。

「ただ現実はそう簡単にはいかない」と牧氏は続ける。UtilやHelper、Managerなどの責務が不明瞭なクラスが量産され、課題が解決しなかった。

明確な設計指針が必要だと考え、採用したのはエリック・エヴァンスのドメイン駆動設計で紹介されているLayard Architecture。

アプリケーションをプレゼンテーション層(情報の表示やユーザー入力の解釈)、アプリケーション層(アプリケーションの要件を実現)、ドメイン層(ビジネスロジックを実現)、インフラストラクチャー層(上位層を支える基盤技術)の4層に分離。上位層は下位層にのみ依存する。

例えば「アプリケーション層はドメイン層とインフラストラクチャー層は参照できるが、上位のプレゼンテーション層は参照できない。

こうすることでレイヤーやクラスが肥大化しにくく、ビジネスロジックのテストが書きやすくなる。加えてレイヤー間で変更が影響しにくく、変更に強くなる。

また、四つの基本的なルールを採用し、チーム内で共通認識を構築。

  • レイヤーをモジュールで表現し、依存関係を守る
  • レイヤー間の結合をinterfaceで疎にする
  • 複雑な要件をObservableで吸収する
  • ドメインモデルの汚染を腐敗防止層で守る

さらに、具体的な設計の例も紹介。

例えばニュースの一覧をAPIから取得して表示するという設計では、「図の様なフローにしました」と説明。

そのほかにも、「APIに負荷がかかるのでアプリでキャッシュする」「SDKから広告を取得して表示」「広告と記事の並び順をクライアント側で決める」などの具体例を紹介した。

最後に牧氏は「今回紹介したのは大規模アプリケーションでも破綻しにくい設計の一例です。解決したい問題に見合った設計を考える必要があります」と語り、セッションを締めた。

Android Thingsで勤怠連絡ボタンを作り、勤怠連絡を簡単に

3番目に登壇したのは、3月末までIoTサービス「myThings」を担当していた松田優貴氏。セッションタイトルは「Android Thingsで勤怠連絡ボタンを作ってみた」

松田氏が今回披露した勤怠連絡ボタンは、例えば「体調が悪く午前中は休む」というような勤怠連絡をPCやスマホで入力することなく、ボタンをポチッと押すだけで完了するツール。

ヤフーでは勤怠連絡をメールで行うことが多いのと、他社ではSlackを利用した勤怠連絡もあるらしいので、Yahoo!メールとSlackを利用することに。そして、せっかくやるなら世の中の風潮に合わせてサーバーレス、クラウドネィティブで実現することを考えた。

その中で「最初はmyThingsアプリ(WebサービスやIoTデバイスが持つ機能を自分で組み合わせて便利に使うことができるアプリ)のみで実現できると思った」と語る。

しかしアプリでは、スマホを起動させる手間に加え、日付を動的に入れることができない。

そこで、ボタンを押すと勝手に連絡が行くようにするため、Hackeyデバイスでできないか検討。

Webhookの機能を利用して、Webscript.ioに飛ばし、myThings Developersプラットフォームを活用して勤怠報告をするというアーキテクチャを考えた。

このアーキテクチャの最大の課題は、URLがバレてしまうと誰でも好きなように勤怠連絡が送れてしまうこと。さらにAmazon Dashボタンを試してみましたが、課題があったという。

次にRaspberry Pi3×SORACOM×AWS IoTを試していたところ、Android Thingsが発表になった。

そして今年、米サンフランシスコで開催された「Google Cloud Next’17」に参加したところ、IoTのセッションではAndroid Thingsが取り上げられており、試してみることに。まずはRaspberry Pi3にAndroid Thingsを入れ、公式ページを参考にしながらセットしていった。

そしてRaspberry Pi3、Android Things、Android Studioを使い、公式ページのLEDチカチカ(Lチカ)サンプルで試した。

Android Studioでは、アプリ開発同様、logcatでログを見られ、モニターをつないでおけば、アプリの画面も表示でき、通常のアプリと同じ感覚でIoTアプリケーションが作れることがわかった。

勤怠連絡ボタンのアーキテクトは図の通り。

「Android Thingsを使う良さは、Android Studioで容易に開発ができること。またGoogleが提供するライブラリを使えるのも良さ。さらにGCP(Pub/Sub、Dataflow、Functionなど)との新和性があるので、クラウド連携がしやすいところもうれしいですね」(松田氏)。

Android Thingsで勤怠連絡ボタンを作る方法の詳細については、松田氏がQiitaにまとめているので、関心のある方はチェックしてみよう。

Yahoo! JAPANアプリのデータベース処理をいかに改善したか

4番目に登壇したのは、昨年10月に中途入社し、現在Yahoo! JAPANアプリの開発を担当している森脇聖太氏。

セッションタイトルは「Yahoo! JAPANアプリのデータベース処理改善」。リリース済みのアプリのデータベース処理をどうやって安全にモダンな環境に移行したかについて話した。

Yahoo! JAPANアプリのAndroid版がリリースされたのは2011年10月。

「リリースから5年以上も経つと、継続的なメンテナンスをしていても、どうしても技術的負債がたまってしまいます。今回はその中でもデータベース周りの負債の解消に取り組むことになりました」(森脇氏)

改修前のデータベース処理の構成は次の通り。

  • SQLiteOpenHelper
  • ContentProvider
  • CursorLoader

それを

  • SQLBrite
  • SQLDelight
  • AutoValue
  • RxJava

などのOSSを用いた構成に改修した。

データベース周りのOSSを導入するにあたって、当初候補に挙がったのは、SQLBriteのほか、Realm、Orma、requeryなど。その中でSQLBriteを選んだ理由として、既存のSQLiteOpenHelperをラップする形で運用できるため、データベースのマイグレーションの必要がなく、他OSSと比べて導入コストが低いことが決め手となったという。

また「SQLDelightと併用することで、Javaの記述とSQLの記述を分離することができ、メンテナンス性が向上しました」と森脇氏。

SQLBrite+SQLDelightを導入して良かった点を次のように明かす。

  • 少ないコストでモダンな開発環境に対応できる
  • データベースのマイグレーションが不要となるので、既存ユーザーのデータ損失リスクを限りなくゼロにできる
  • SQLとJavaの記述を分離することで、可読性が向上

一方、つらかった点もある。それはSQLBriteがRxJava2に未対応であること(4月現在)、日本ではRealmやOrmaの知名度が圧倒的に高いため、チーム内への布教活動がかなり必要になることだ。

「既存アプリのデータベース改修は大変。世の中にはORMがいっぱいだが、SQLiteOpenHelperを使っているなら、SQLBrite+SQLDelightという選択肢もありだと思います」(森脇氏)

不具合で学んだ[最適」への道

5番目に登壇したのは、12年に新卒で入社して以来、昨年の7月までずっとYahoo!ニュースアプリを担当してきた矢端智光氏。セッションタイトルは「ニュースアプリで起きた不具合から学んだ最適への一歩」。

ニュースアプリで起きた不具合から学んだ 最適への一歩 from Yahoo!デベロッパーネットワーク

Yahoo!ニュースアプリ Android Things版1.0.0をリリースされたのは13年11月20日。「3周年が過ぎたので、最適について考えてみました。中でも、最適をおざなりにしてきたのは開発者に対してでした」と矢端氏は語る。

Yahoo!ニュースアプリの歴史はまだ短いため、プロダクション優先やユーザー優先で開発されてきたこと。そして業務委託やオフショア開発など、開発体制が定期的に変化していたことがその理由だと振り返った。

開発の大半に関わってきたなかで、次のような反省があると明かす。

それは直したバグをプルリクエストするだけで、事例としてまとめて整理していなかったこと。そのため、類似の事象が発生した時に過去の資料を探すという無駄な時間がかかってしまっていたこと。これらのことに開発から離れて気付いたという。

開発者に対して最適にするため、まず行ったのはバグの事例を振り返ることだった。そのためにVolleyとの別れを決断。かゆいところに手が届くように刷新したので、手がかかりすぎようになり刷新が必要になったからだ。

例えばレスポンスヘッダーのキーが大文字小文字関係なく取得できるようにしたり、特定機種やOSで発生したりする意図せぬエラーをハンドリングするなど、つぎはぎしていた項目も刷新した。

実際に「一覧画面のFragmentに機能を追加したらエラーとなった」というバグ事例を紹介。この原因は、ViewPager上の二つの画面が「自分を更新する」メソッドをonResumeのタイミングで同時に呼んだこと。それを解決するため、「自分を更新する」メソッドが複数回呼ばれた場合に、一度だけ実行されるように修正することに。

だが、この解決方法を実装すると、フラグが氾濫し、コードが冗長になってしまう。そこでHandlerで実行するRunnableを制御する実装を行うことで解決を図った。

ただし「処理をずらすので、書き方次第では実行されるまでの間に、参照している値やメソッドの返り値に変更が発生する可能性があることは念頭においておきましょう」とのこと。

最後に「バグは恥ずかしいものかもしれないが、誰にも聞けないというふうにしないこと。周りのできる人も手を差し伸べてあげてください。そして不具合に対するナレッジを共有することで最適への一歩を踏み出してください」と呼びかけた。

タブブラウザSDKを作った話

最後のセッションは、Yahoo! JAPANアプリを担当している小林俊氏による「タブブラウザSDKを作った話」。

タブブラウザSDKを作った話 #yjcamp from Yahoo!デベロッパーネットワーク

ちなみにタブブラウザSDKとは、WebView管理やタブ管理ができ、CoordinatorLayout対応、URLスキーマハンドリング、ページ内検索、標準的な振る舞いを提供してくれるSDK。セッションでは3桁を実現させるタブ管理、WebViewとCoordinatorLayoutの実装方法を中心に説明が行われた。

ブラウザ機能をSDK化することで、ブラウザ周りのシステム改修を各アプリでする必要がない。3桁を実現させるタブ管理では、タブとタブの持つWebViewをそれぞれ独立して管理するのが特徴。上限を超えたWebViewは、最もアクセス時刻の古いものから破棄されるようになっている。

破棄されたWebViewの保存はWebViewが提供するメソッドをそのまま利用し、Bundleを通してファイルへの保存し、再度タブが開かれた時に、ファイルからBundleへ読み込みWebViewのメソッドで復元させる。

WebViewとCoordinatorLayoutの対応をする場合は、地図操作、カルーセル、ピンチイン・アウトなど、横スクロールした時に縦スクロールが発生することによるWebViewの移動や、サイズ変更による操作の阻害への対応について紹介した。

タブがカルーセルタイプの場合、横スクロールする時に縦スクロールが発生することによって、 WebViewの移動やサイズ変更による操作の阻害が起こることがある。

地図操作の場合は、WebViewサイズいっぱいで 操作させるページで動かないようにサイトのコンテンツサイズ(高さ)と WebViewのサイズを比較しながら対応する。

最後に、「WebViewにNestedScrollChildを実装」「ウェブサイトの作りへの考慮が必要」とまとめた。

セッションの後は懇親会を開催。懇親会には登壇者のほかにも、ヤフー社員が参加しており、参加者たちは思い思いに情報交換にいそしんでいた。

ヤフーではさまざまな技術に関する勉強会やイベントを開催している。エンジニア向けイベント開催情報はヤフーのエンジニア向けオウンドメディア「linotice」をチェックしてみよう。

  • 15
  • このエントリーをはてなブックマークに追加

■関連記事

実数論、微分方程式、代数、離散数学、トポロジー「プログラマのための数学勉強会」第4回レポート... 今回のテーマと目次 「プログラマのための数学勉強会」第4回からは、各セッションの難易度を星3つで示すようになった。 何もないところから数を作る(集合論、実数論) 難易度★☆☆ 今日からはじめる微分方程式(微分方程式、ラプラス変換) 難易度★★☆ 忙しい人のための楕円曲線入門(代数...
物理における『微分方程式』の活用─プログラマのための数学勉強会6... 物理における微分方程式の活用 久徳浩太郎氏が所属している理化学研究所 iTHES(理論科学連携研究推進グループ)は、理論化学を研究しているグループ。また同グループでは産学連携も積極的に推進しているという。 そんな中で久徳氏は宇宙物理や理論物理を研究している。つまり今回唯一の物理屋。しかし「物理屋...
最適化問題を「線形計画法と整数計画法」で解く─プログラマのための数学勉強会5... 線形計画法と整数計画法 本来はカーマーカーの話を予定していたが、「誰得?」ということで、整数計画法の話に変更したというエウレカのkaneshin氏。 「最適化問題を認知してもらうきっかけになると嬉しい」と語り発表をスタートさせた。実は大学時代最適化問題の非線形計画法を専攻していたというが、「今日...
曲面のつながり方・まがり方・大きさの関係を幾何学的に捉える─プログラマのための数学勉強会4... つながり方・まがり方・大きさ matsumoring氏の発表タイトルは「つながり方・まがり方・大きさ」。「今日は幾何学の話。プログラミングとは関係ない」と前置きしながらも、正多面体や球面などの立体図形を題材に簡単な計算をすることで、図形のつながり方・まがり方・大きさの関係を紹介。 この発表で...
五次方程式は、なぜ解けないのか?─プログラマのための数学勉強会3... 「五次方程式がなぜ解けないのか」を証明する 2番目に登壇したのは、日曜数学者の辻順平(id:tsujimotter)氏。発表タイトルは「五次方程式が代数的に解けないわけ」。 第1回の勉強会でゼータ関数の話をした辻氏は、「実際に触りたいと思い、3Dプリンタでゼータ関数を作った」とゼータ関数の模型を...
線形代数入門『基底変換と固有値・固有ベクトル』を理解する─プログラマのための数学勉強会2... 線形代数入門の最終章「基底変換と固有値・固有ベクトル」を理解する 佐野氏は「まずはこれまでの復習から」と語り、線形変換の説明に入った。線形変換は空間の平行と比率を保つ変換である。以下の図を見れば分かるとおり(1,0)と(0,1)が移った先を取りさえすれば、変換の全体ができてしまう。 式も図の通り...

今週のPickUPレポート

新着記事

週間ランキング

CodeIQとは

CodeIQ(コードアイキュー)とは、自分の実力を知りたいITエンジニア向けの、実務スキル評価サービスです。

CodeIQご利用にあたって
関連サイト
codeiq

リクルートグループサイトへ