RefreshShows () в репозитории вызывается каждый раз, когда вызывается обратный вызов onCreate () Activity - PullRequest
0 голосов
/ 29 мая 2020

У меня есть следующий проект в Github: https://github.com/Ali-Rezaei/TVMaze

Я начал использовать Koin в качестве инфраструктуры для внедрения зависимостей в примере приложения:

class TVMazeApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        startKoin {
            androidContext(this@TVMazeApplication)
            modules(networkModule)
            modules(persistenceModule)
            modules(repositoryModule)
            modules(viewModelModule)
        }
    }
}

Это это мой класс репозитория:

class ShowRepository(
    private val dao: ShowDao,
    private val api: TVMazeService,
    private val context: Context
) {

    /**
     * A list of shows that can be shown on the screen.
     */
    val shows = resultLiveData(
        databaseQuery = {
            Transformations.map(dao.getShows()) {
                it.asDomainModel()
            }
        },
        networkCall = { refreshShows() })

    /**
     * Refresh the shows stored in the offline cache.
     */
    private suspend fun refreshShows(): Result<List<Show>> =
        try {
            if (isNetworkAvailable(context)) {
                val shows = api.fetchShowList().await()
                dao.insertAll(*shows.asDatabaseModel())
                Result.success(shows)
            } else {
                Result.error(context.getString(R.string.failed_internet_msg))
            }
        } catch (err: HttpException) {
            Result.error(context.getString(R.string.failed_loading_msg))
        }
}

И моя ViewModel:

class MainViewModel(
    repository: ShowRepository
) : ViewModel() {

    private val _shows = repository.shows
    val shows: LiveData<Result<List<Show>>>
        get() = _shows
}

И я наблюдаю LiveData в своей деятельности:

viewModel.shows.observe(this, Observer { result ->
            when (result.status) {
                Result.Status.SUCCESS -> {
                    binding.loadingSpinner.hide() 
                    viewModelAdapter.submitList(result.data)
                }
                Result.Status.LOADING -> binding.loadingSpinner.show()
                Result.Status.ERROR -> {
                    binding.loadingSpinner.hide()
                    Snackbar.make(binding.root, result.message!!, Snackbar.LENGTH_LONG).show()
                }
            }
        })

Когда я нажимаю кнопку «Назад» , Действия уничтожаются (но экземпляр приложения все еще существует, поскольку я могу получить к нему доступ из недавних приложений). Я ожидаю вызова метода refreshShows (), когда я снова запускаю приложение, но он никогда не вызывается.

Но когда я уничтожаю экземпляр приложения, очищая его от недавнего приложения и запускаю приложение, refreshShows () получить вызов.

Что мне делать, чтобы вызывать функцию refreshShows () каждый раз, когда вызывается onCreate() обратный вызов Activity?

fun <T, A> resultLiveData(databaseQuery: () -> LiveData<T>,
                          networkCall: suspend () -> Result<A>): LiveData<Result<T>> =
    liveData(Dispatchers.IO) {
        emit(Result.loading<T>())
        val source = databaseQuery.invoke().map { Result.success(it) }
        emitSource(source)

        val result = networkCall.invoke()
        if (result.status == Result.Status.ERROR) {
            emit(Result.error<T>(result.message!!))
            emitSource(source)
        }
    }

1 Ответ

0 голосов
/ 29 мая 2020

Ваш refreshShows () в вашем репозитории вызывается только при выполнении нового сетевого запроса. Идея ваших живых данных состоит в том, чтобы предоставить последний результат при воссоздании его фрагмента / активности, поэтому, когда ваш экран вращается или вы возобновляете действие, он не запускает другой запрос, поскольку у живых данных уже есть последний результат, и у вас нет соединения с отслеживанием состояния с ваша сетевая база данных / сервер (если вы наблюдаете за данными из комнаты, он получит последнее изменение, если таковое имеется).

Самый простой способ, который я нашел, чтобы "исправить" это, - это действительно иметь вашу модель просмотра val показывает как развлечение, например:

class MainViewModel(
    repository: ShowRepository
) : ViewModel() {

    private val _shows = repository.shows()
    val shows: LiveData<Result<List<Show>>>
        get() = _shows
}

Однако при таком использовании каждый раз, когда экран вращается, будет выполняться новый сетевой вызов, таким образом вызывая ваш refreshShows ()

...