Android Kotlin基礎講座 09.1:レポジトリー

タスク:リフレッシュ手法を使ってレポジトリーを統合する

このタスクでは、シンプルなリフレッシュ手法を使って、レポジトリーとViewModelを統合します。ネットワークから直接読み取ってではなく、Roomデータベースから動画のプレイリストを表示します。

データベースのリフレッシュとはローカルデータベースとネットワークからのデータを常に同期させるために更新したりリフレッシュしたりするプロセスのことです。このサンプルアプリでは、とてもシンプルなリフレッシュ手法を使います。レポジトリーからデータをリクエストするモジュールでローカルデータのリフレッシュを行います。

実世界のアプリでは、この手法はもっと複雑なものになります。例えば、バックグラウンドで自動でデータをリフレッシュさせたり、ユーザーが次に使う可能性が高いデータをキャッシュさせたりなどです。

  1. viewmodels/DevByteViewModel.kt内、DevByteViewModelクラス内にprivateのVideoRepository型のvideosRepositoryというメンバ変数を作成してください。この変数をVideosDatabaseというシングルトンのオブジェクトを渡してインスタンス化してください。
/**
* The data source this ViewModel will fetch results from.
*/
private val videosRepository = VideosRepository(getDatabase(application))
  1. DevByteViewModelクラス内のrefreshDataFromNetwork()メソッドをrefreshDataFromRepository()メソッドで置き換えてください。

置き換える前のメソッド、refreshDataFromNetwork()はRetrofitライブラリを使ってネットワークからプレイリストを読み取っていました。新しいメソッドはレポジトリーからプレイリストを読み込みます。

/**
* Refresh data from the repository. Use a coroutine launch to run in a
* background thread.
*/
private fun refreshDataFromRepository() {
   viewModelScope.launch {
       try {
           videosRepository.refreshVideos()
           _eventNetworkError.value = false
           _isNetworkErrorShown.value = false

       } catch (networkError: IOException) {
           // Show a Toast error message and hide the progress bar.
           if(playlist.value.isNullOrEmpty())
               _eventNetworkError.value = true
       }
   }
}
  1. DevByteViewModelクラス内、initブロック内のrefreshDataFromNetwork()の呼び出しをrefreshDataFromRepository()に変更してください。このコードはネットワークから直接ではなく、レポジトリーからプレイリストを読み込みます。
init {
   refreshDataFromRepository()
}
  1. DevByteViewModelクラス内の_playlistプロパティとそのバッキングプロパティであるplaylistを削除してください。

削除するコード:

private val _playlist = MutableLiveData<List<Video>>()
...
val playlist: LiveData<List<Video>>
   get() = _playlist
  1. DevByteViewModelクラス内のvideosRepositoryオブジェクトのインスタンス化のあとに、レポジトリーから読み取った動画のLiveDataリストを保持するためのplaylistというvalを作成してください。
/**
* A playlist of videos displayed on the screen.
*/
val playlist = videosRepository.videos
  1. アプリを起動してください。以前と同じようにアプリが起動しますが、現在DevBytesプレイリストはネットワークから取得され、Roomデータベースに保存されています。プレイリストはネットワークから直接ではなく、Roomデータベースから表示されています。
  1. 違いを確認するために、機内モードをオンにしてください。
  2. アプリをもう一度起動してください。”Network Error”トーストメッセージが表示されないことを確認してください。代わりにオフラインキャッシュからプレイリストが読み込まれ、表示されています。
  3. 機内モードをオフにしてください。
  4. アプリを閉じて、もう一度開いてください。ネットワークリクエストがバックグラウンドで動作している間にオフラインキャッシュからプレイリストを読み込んでいます。

新しいデータがネットワークから入ってきた場合、画面は自動で新しいデータを表示するように更新されます。しかしながら、DevBytesサーバーはコンテンツをリフレッシュすることはないので、データの更新を見ることはないでしょう。

Tip: テスト用にキャッシュを削除する最も簡単な方法はアプリをアンインストールすることです。

お疲れさまでした。この記事では、Roomを使ったオフラインキャッシュを実装し、レポジトリーにキャッシュを取り付け、transformationを使ってLiveDataを操作しました。また、オフラインキャッシュをViewModelと統合して、ネットワークからプレイリストを読み取るのではなく、レポジトリーから読み取って表示するようにしました。

完成済みプロジェクト

お疲れさまでした。完成済みプロジェクトは以下からダウンロードできます。

DevBytesRepository