В моем текущем проекте Android у меня есть диалоговое окно, которое извлекает список объектов из веб-службы и показывает их в списке. Однако у него есть проблема. Веб-сервис (вне моего контроля) не самый быстрый, поэтому процесс занимает некоторое время, и часто пользователь меняет ориентацию устройства, пока этот процесс продолжается. На данный момент изменение ориентации приводит к отмене исходного вызова веб-службы и созданию нового, но я знаю, что это не так. Я хотел бы, чтобы диалоговое окно могло продолжить загрузку из веб-сервиса, когда происходит изменение ориентации, но я просто не могу понять, как это сделать. Как можно подключиться к текущему вызову и отобразить это состояние в представлении (диалоге)? Любые рекомендации приветствуются. Я играл с компонентами архитектуры Android и закрытыми классами kotlins, сохраняя состояние представления в объекте livedata, который наблюдает представление, но не нашел решения, которое мне нравится.
Я считаю, что многие разработчики используют RxJava для решения таких проблем. Это мой единственный вариант?
Кстати. на данный момент я использую архитектуру MVP в своем проекте.
Изменить
Здесь я отменяю задание - если прослушиватель равен нулю, он отменяется (я использую сопрограммы kotlin):
override fun getWorklist() {
job = onWorkerThread {
val result = repository.getResult().awaitResult()
onMainThread {
when (result) {
is Result.Ok -> listener?.onResult(result.getOrDefault(emptyList())) :? job.cancel()
// Any HTTP error
is Result.Error -> listener?.onHttpError(result.exception) :? job.cancel()
// Exception while request invocation
is Result.Exception -> listener?.onException(result.exception) :? job.cancel()
}
}
}
}
Изменить 2
Я пытался управлять состоянием представления с помощью этой Android Arch ViewModel, но объект MediatorLiveData не запускается при изменении объекта состояния представления. И вид остается в состоянии загрузки:
class MainModel : ViewModel() {
private var job: Job? = null
val viewState = MutableLiveData<MainViewState>().apply { value = Loading("Warsaw") }
val dataGetter = MediatorLiveData<MainViewState>().apply {
addSource(viewState, {
Log.d("MainModel", "Viewstate is: " + viewState.value.toString() + ")...")
when(it) {
is Loading -> {
Log.d("MainModel", "Launching coroutine...")
job = launch(UI) {
Log.d("MainModel", "Loading...")
val items = Repository.getWorklist()
Log.d("MainModel", "Charts retrieved...")
[email protected](Success(it.items))
Log.d("MainModel", "Posted update to viewstate...")
}
}
}
})
}
override fun onCleared() {
Log.d("MainModel", "Clearing ViewModel")
job?.cancel()
}
}
interface ViewState
sealed class MainViewState : ViewState
class Loading() : MainViewState()
class Error(val error: String) : MainViewState()
class Success(val items: List<WorklistItem>) : MainViewState()
onDestroy()
, как это бывает чаще всего. Вы можете добавить следующие строки в свой основной файл под действиемandroid:configChanges="orientation|screenSize"
. Обычно при изменении ориентации действие уничтожается и создается заново, это в основном говорит о том, что вы будете обрабатывать изменения макета самостоятельно. - person Abbas   schedule 30.01.2018