「ページングライブラリ」でデータベースにキャッシュしながらページングする方法
一歩進んだAndroidアプリ開発ができる「Android Jetpack」入門 第14回
本連載は、「Android Studio2で始めるアプリ開発入門」連載、および『Androidアプリ開発の教科書』の続編にあたる内容として、Jetpackを取り上げていきます。前回は、ページングライブラリを利用してネット上にあるリストデータをページングする方法を紹介しました。今回は、ネット上のリストデータをいったんデータベースに格納した上でページングする方法を紹介します。
RemoteMediatorの概要とその利用準備
本連載は、Android Jetpackを紹介しています。今回は、大量のデータを効率よく扱えるページングライブラリを利用して、ネット上にあるリストデータをいったんデータベースに格納した上でページングする方法を解説します。
なお、今回のサンプルデータは、GitHubから参照できます。ただし、サンプル内のコードでは実際にネットにアクセスしてデータを取得するコードは記載せず、ダミーでデータを生成するコードとなっている点はあらかじめご了承ください。
PagingSourceクラスとネットアクセスの問題点
前回紹介したように、PagingSourceクラスを自作し、その中にネット上のリストデータを取得するコードを記述すれば、ネット上にある大量のデータをページングしながら表示することが可能です。
ただし、この方法には問題があります。まず、当たり前ですが、オフラインの時にはデータを取得できません。さらに、リストを前のページに戻した時、すなわち以前表示したデータを再表示する際にもネットアクセスが発生してしまいます(※)。
※実際にはメモリ上にリストデータが存在するのですぐにアクセスが発生するわけではありません。
Androidにはオフラインファーストという考え方があります。これはすなわち、可能な限りオフラインでもデータ表示が可能なことを前提にアプリを作成する考え方です。
先述の問題を解決し、オフラインファーストを実現するならば、いったん取得したネット上のリストデータはデータベースに格納した上で、そのデータを表示する必要があります。つまり、データベースへのキャッシュが有効です。
そしてページングライブラリには、これを効率よく実現してくれる仕組みがあります。
RemoteMediatorの働き
それが、RemoteMediatorクラスです。
RemoteMediatorクラス内では、ページングライブラリから呼び出された際にデータベース内の現在のデータの状態を確認し、それに基づいて続きのデータをネット上から取得し、データベースに格納します。
そのデータベースのデータを元に生成されたPagingSourceを利用することで、第12回で紹介した内容と同じく、ページング表示が可能になります(図1)。
この仕組みにより、ネット上のデータをデータベースにキャッシュしながらページング表示が可能です。
ここから、実際にRemoteMediatorの使い方を紹介していきます。
その際の題材は、前回と第12回の組合せのようなものです。ネット上から電話番号リストを取得し、それをデータベース上のphonesテーブルにキャッシュすることにします。
したがって、第12回で登場したRoomによるphonesテーブルの操作に必要なクラスや、前回登場したネット上のリストデータを取得するsuspend関数(Javaの場合はCallableインターフェースを実装したクラス)が、そのまま登場します。
DAOにメソッドを追加
ただし、PhoneDAOには改造が必要です。というのは、RemoteMediatorを利用する場合、前項での説明の通り、RemoteMediator内でネット上から取得したデータをデータベースに格納するコードを記述する必要があります。
そのためには、DAOインターフェースにそのメソッドを追加しておく必要があります。これは例えばリスト1のコードとなります。
@Dao
interface PhoneDAO {
@Query("SELECT * FROM phones ORDER BY id") // (1)
fun findAll(): PagingSource<Int, Phone> // (1)
@Insert(onConflict = OnConflictStrategy.REPLACE) // (2)
suspend fun insertPhoneList(phones: List<Phone>) // (2)
@Query("DELETE FROM phones") // (3)
suspend fun deleteAll() // (3)
@Query("SELECT MAX(id) FROM phones") // (4)
suspend fun findLastId(): Long // (4)
}
リスト1の(1)は、第12回のリスト2にも記述されていたメソッドです。
これに(2)~(4)が追加されています。前項で紹介したように、RemoteMediatorではネット上から取得したリストデータをデータベースに格納する必要があります。そのメソッドが(2)です。アノテーションにデータのコンフリクトが起きた際は、丸々置き換えるようにしてあるのがポイントです。
(3)は全データの削除メソッドです。RemoteMediator内のコーディングの際に紹介するように、キャッシュのクリアの意味でデータベース内の全データを削除するタイミングがあります。その際に利用するメソッドです。
(4)は、データベース内のidの最大値を取得するメソッドです。この結果を元に、データベース内にどこまでのリストデータが格納されているのかを判断し、続きをネット上から取得するようにします。
この記事は参考になりましたか?
- 一歩進んだAndroidアプリ開発ができる「Android Jetpack」入門連載記事一覧
- この記事の著者
-
WINGSプロジェクト 齊藤 新三(サイトウ シンゾウ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。Web系製作会社のシステム部門、SI会社を経てフリーランスとして独立。屋号はSarva(サルヴァ)。HAL大阪の非常勤講師を兼務。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
