NIKKEI Digital Recruiting Site

日経電子版Androidの記事読み込みを快適にする技術

本稿では記事読み込み中のプログレスダイアログによる UI ロックを取り去る改善について解説を行う。

読み込み中の画面ロック外し

図の通り旧電子版 Android アプリは新しい記事が配信されるタイミングでプログレスダイアログを表示し、UI を完全にロックしてしまっていた。これを Android 標準のコンポーネントである SwipeRefreshLayout で置き換えた。ここで更に重要な点として、新しい記事データを読み込んでいる間に、いま表示している記事の一覧画面を自由にスクロールしたり個別の記事を閲覧したりできるようにした。

このためにはまず「時間のかかる非同期処理」と「各画面のライフサイクル」を切り離す必要がある。これまでは UI を完全にロックしていたのでユーザは非同期処理が終わるまでずっと待たされていた。これは非同期処理のハンドリングがシンプルになるが、次の行動を阻害することになるためユーザ体験は非常に悪いものになる。

各画面より長い非同期処理と通知

ここで図のように非同期処理を担う「モデル層」は基本的にはアプリケーションシングルトンとしてアプリと同じライフサイクルで非同期処理をしつつ、完了するとそれを各画面に「通知」するように実装した。これにより、各画面より長いタスクも効率的かつ自然に扱うことができる。非同期処理の結果も、各画面にコールバックとして戻してやるのではなく、いわゆる EventBus のようなオブザーバーとして結果を受け取れるようにする。各画面は

  1. 表示されたときに非同期処理が実行されていなければモデルに記事の取得を依頼する
  2. すでに取得依頼している場合はロード中を示す View を表示する
  3. 非同期処理が完了する前に画面から去る場合は Event を受け取らない
  4. 画面が表示されている間に非同期処理が完了すればロード中を示す View を非表示にし新しい結果で画面を更新する

という大きな流れとなる。

実際には日経電子版 Android の非同期処理基盤は Java の標準のコンポーネントである ThreadPoolExecutor で実装されており、各画面は自分が行って欲しい非同期処理をここにどんどんキューイングしていく。しかしながら、投げっぱなしでは制御ができないので、キューイングしたときに Request オブジェクトをもらっている。これは

  1. 各リクエストを表す UUID
  2. リクエストのまとまりを表現する GroupID

の 2 つを持っており、リクエストを個別/グループ単位でキャンセルしたり現在の状態を問い合わせたりすることができるように設計されている。今回の施策では画面ごとに GroupID を共通化することで、いまその画面ですでにニュース記事の読み込みが始まったか終わったかを調べつつ View を更新することができるようにしている。

ThreaedPoolEventBus による通知は古典的だが今なお強力なテクニックであるので是非参考にして欲しい。

白山文彦
ENGINEER白山文彦

Entry

各種エントリーはこちらから

キャリア採用
Entry
新卒採用
Entry