import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
suspend fun allPlants(): List<Plant> = withContext(Dispatchers.Default) {
delay(1500)
val result = sunflowerService.getAllPlants()
result.shuffled()
}
import kotlinx.coroutines.flow.Flow
@Query("SELECT * from plants ORDER BY name")
fun getPlantsFlow(): Flow<List<Plant>>
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapLatest
private val growZoneFlow = MutableStateFlow<GrowZone>(NoGrowZone)
val plantsUsingFlow: LiveData<List<Plant>> = growZoneFlow.flatMapLatest { growZone ->
if (growZone == NoGrowZone) {
plantRepository.plantsFlow
} else {
plantRepository.getPlantsWithGrowZoneFlow(growZone)
}
}.asLiveData()
init {
clearGrowZoneNumber()
growZoneFlow.mapLatest { growZone ->
_spinner.value = true
if (growZone == NoGrowZone) {
plantRepository.tryUpdateRecentPlantsCache()
} else {
plantRepository.tryUpdateRecentPlantsForGrowZoneCache(growZone)
}
}
.onEach { _spinner.value = false }
.catch { throwable -> _snackbar.value = throwable.message }
.launchIn(viewModelScope)
}
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch
private fun launchDataLoad(block: suspend () -> Unit): Job {
return viewModelScope.launch {
try {
_spinner.value = true
block()
} catch (error: Throwable) {
_snackbar.value = error.message
} finally {
_spinner.value = false
}
}
}
import androidx.work.CoroutineWorker
import androidx.work.ListenableWorker
import androidx.work.WorkManager
import androidx.work.Worker
import androidx.work.WorkerFactory
import androidx.work.WorkerParameters
class RefreshMainDataWork(context: Context, params: WorkerParameters, private val network: MainNetwork) :
CoroutineWorker(context, params) {
/**
* Refresh the title from the network using [TitleRepository]
*
* WorkManager will call this method from a background thread. It may be called even
* after our app has been terminated by the operating system, in which case [WorkManager] will
* start just enough to run this [Worker].
*/
override suspend fun doWork(): Result {
val database = getDatabase(applicationContext)
val repository = TitleRepository(network, database.titleDao)
return try {
repository.refreshTitle()
Result.success()
} catch (error: TitleRefreshError) {
Result.failure()
}
}
class Factory(val network: MainNetwork = getNetworkService()) : WorkerFactory() {
override fun createWorker(appContext: Context, workerClassName: String, workerParameters: WorkerParameters): ListenableWorker? {
return RefreshMainDataWork(appContext, workerParameters, network)
}
}
}
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeout
/**
* This API is exposed for callers from the Java Programming language.
*
* The request will run unstructured, which means it won't be able to be cancelled.
*
* @param titleRefreshCallback a callback
*/
fun refreshTitleInterop(titleRefreshCallback: TitleRefreshCallback) {
val scope = CoroutineScope(Dispatchers.Default)
scope.launch {
try {
refreshTitle()
titleRefreshCallback.onCompleted()
} catch (throwable: Throwable) {
titleRefreshCallback.onError(throwable)
}
}
}
}