Advertisement
Guest User

Untitled

a guest
Oct 21st, 2019
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Kotlin 3.62 KB | None | 0 0
  1. /*
  2.  * Copyright 2018 Google LLC
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  *     https://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16.  
  17. package com.example.android.kotlincoroutines.main
  18.  
  19. import androidx.lifecycle.LiveData
  20. import androidx.lifecycle.Transformations
  21. import com.example.android.kotlincoroutines.util.*
  22. import kotlinx.coroutines.Dispatchers
  23. import kotlinx.coroutines.withContext
  24. import kotlin.LazyThreadSafetyMode.NONE
  25. import kotlin.coroutines.resume
  26. import kotlin.coroutines.resumeWithException
  27. import kotlin.coroutines.suspendCoroutine
  28.  
  29. /**
  30.  * TitleRepository provides an interface to fetch a title or request a new one be generated.
  31.  *
  32.  * Repository modules handle data operations. They provide a clean API so that the rest of the app
  33.  * can retrieve this data easily. They know where to get the data from and what API calls to make
  34.  * when data is updated. You can consider repositories to be mediators between different data
  35.  * sources, in our case it mediates between a network API and an offline database cache.
  36.  */
  37. class TitleRepository(private val network: MainNetwork, private val titleDao: TitleDao) {
  38.  
  39.     /**
  40.      * [LiveData] to load title.
  41.      *
  42.      * This is the main interface for loading a title. The title will be loaded from the offline
  43.      * cache.
  44.      *
  45.      * Observing this will not cause the title to be refreshed, use [TitleRepository.refreshTitle]
  46.      * to refresh the title.
  47.      *
  48.      * Because this is defined as `by lazy` it won't be instantiated until the property is
  49.      * used for the first time.
  50.      */
  51.     val title: LiveData<String> by lazy<LiveData<String>>(NONE) {
  52.         Transformations.map(titleDao.loadTitle()) { it?.title }
  53.     }
  54.  
  55.     /**
  56.      * Refresh the current title and save the results to the offline cache.
  57.      *
  58.      * This method does not return the new title. Use [TitleRepository.title] to observe
  59.      * the current tile.
  60.      *
  61.      * @param onStateChanged callback called when state changes to Loading, Success, or Error
  62.      */
  63.     suspend fun refreshTitle() {
  64.         withContext(Dispatchers.IO) {
  65.             try {
  66.                 val result = network.fetchNewWelcome().await()
  67.                 titleDao.insertTitle(Title(result))
  68.             } catch (error: FakeNetworkException) {
  69.                 throw TitleRefreshError(error)
  70.             }
  71.         }
  72.     }
  73. }
  74.  
  75. /**
  76.  * Thrown when there was a error fetching a new title
  77.  *
  78.  * @property message user ready error message
  79.  * @property cause the original cause of this exception
  80.  */
  81. class TitleRefreshError(cause: Throwable) : Throwable(cause.message, cause)
  82.  
  83. /**
  84.  * Suspend function to use callback-based [FakeNetworkCall] in coroutines
  85.  *
  86.  * @return network result after completion
  87.  * @throws Throwable original exception from library if network request fails
  88.  */
  89. suspend fun <T> FakeNetworkCall<T>.await(): T {
  90.     return suspendCoroutine { continuation ->
  91.         addOnResultListener { result ->
  92.             when(result) {
  93.                 is FakeNetworkSuccess<T> -> continuation.resume(result.data)
  94.                 is FakeNetworkError -> continuation.resumeWithException(result.error)
  95.             }
  96.         }
  97.     }
  98. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement