Как обеспечить глобальный "кеш" для текущего сеанса пользователя, даже если процесс убит - PullRequest
1 голос
/ 03 августа 2020

Я постараюсь быть как можно более ясным и точным в своей ситуации.

В настоящее время разрабатывая приложение Android с Koltin на основе шаблона MVVM, я столкнулся с проблемой, которая ставит под сомнение мою архитектуру.

Мое приложение состоит в получении различных заказов пользователя, каждый из которых имеет список продуктов.

Я представлял себе настройку «CommandController», который на самом деле является синглтоном.

object CommandController : ICommandController {
override var m_commandRepository: ICommandRepository = CommandRepository()
override var m_commandList: MutableList<Command> = mutableListOf<Command>()
override var m_currentCommand: Command? = null

override var m_currentProduct : Produit? = null
override var m_currentProductIndex : Int = first_index

}

Цель этого синглтона - действовать как посредник между моими моделями просмотра и моим репозиторием, чтобы хранить полученные команды и текущую активную команду (только 1 активная команда в время).

 class CommandListViewModel : ViewModel() {
    fun fetchCommandList(refreshStrategy: CommandRefreshStrategy){
            viewModelScope.launch {
                mProgressBar.postValue(true)
                mErrorStatus.postValue(null)
                try {
                    mCommandList.postValue(CommandController.getCommandsList(refreshStrategy)) //USE CONTROLLER HERE
                    mCommandActive.postValue(CommandController.getCurrentCommand()) //USE CONTROLLER HERE
                }
                catch (e: Exception) {
                    //this is generic exception handling
                    //so inform user that something went wrong
                    mErrorStatus.postValue(ApiResponseError.DEFAULT)
                }
                finally {
                    mProgressBar.postValue(false)
                }
    
            }
    }
}

Обратите внимание, что ни один элемент не имеет ссылки на синглтон, kotlin инициализирует его, когда он сначала нужен

Если я нажму на активная команда в списке, я показываю ее детали

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

Итак, мои слои следующие:

MVVM

Проблема, о которой я не знал, раздражает.

Действительно, если я изменяю разрешения, предоставленные приложением, и возвращаюсь в приложение, последнее запущенное действие будет воссоздан в последнем посещенном фрагменте.

Проблема в том, что мой синглтон возвращается в исходное состояние, поэтому моя активная команда равна нулю, потому что процесс был прерван системой после изменения разрешений.

Итак, я хотел бы знать, есть ли способ сохранить / восстановить состояние моего синглтона, когда я вернусь в приложение.

Я уже пытался передать свой синглтон в класс, унаследованный от Приложение, но это не решает проблему убитого процесса.

Я читал много статей / тем об общих предпочтениях, но у меня много проблем с ним:

  1. Контроллер должен быть чисто бизнес-элементом, за исключением того, что для общих настроек нужен контекст

  2. Я не хочу Текущая команда и список команд, которые останутся, если пользователь сам завершит работу приложения (есть ли способ различить смерть процесса системой и пользователем ??).

1 Ответ

1 голос
/ 05 августа 2020

Android уничтожит процессы ОС по разным причинам. Если вы хотите, чтобы ваши данные пережили это, вы должны хранить их в постоянном хранилище. Одно из следующих:

  • Сохранить в файле
  • Сохранить в SharedPreferences
  • Сохранить в базе данных SQLite
  • Сохранить это в облаке на каком-то сервере, откуда вы можете получить его позже
...