Где делать запросы API при использовании архитектуры MVVM в android? - PullRequest
0 голосов
/ 14 марта 2020

Я использую архитектуру MVVM в своем приложении и хочу сделать запросы API из класса viewmodel действия. Проблема в том, что я не получаю лучший способ сделать это. Поскольку viewmodel уже осведомлен об этом действии, поэтому нет необходимости создавать отдельный класс viewmodel для API? Если это так, то должен ли я запускать обычные запросы на модернизацию из класса viewmodel или каков будет лучший подход в этом сценарии?

То, что я делал раньше без MVVM, таково:

class UserViewModel : ViewModel() {

    private val cd = CompositeDisposable()
    val status: MutableLiveData<Boolean>? = MutableLiveData<Boolean>()


    val responseImages = MutableLiveData<ResponseImages>()
    fun getImages(text: String) {
        cd.add(
            RetrofitHelper.apiInstance.getImages(Site.METHOD, Site.KEY, text)
                .myApiSubscriber(status)
                .subscribe({
                    responseImages.postValue(it)
                }, {
                    it.printStackTrace()
                })
        )
    }


    private fun <T> Single<T>.myApiSubscriber(status: MutableLiveData<Boolean>?): Single<T> {
        return this.doOnSubscribe {
            status?.postValue(true)
//            Utils.debugger("PROGRESS ", " doOnSubscribe")
        }.doFinally {
            status?.postValue(false)
//            Utils.debugger("PROGRESS ", " doFinally")
        }.subscribeOn(Schedulers.io())
    }

    override fun onCleared() {
        cd.dispose()
        super.onCleared()
    }

    fun callCleared() {
        onCleared()
    }
}

, так как описанный выше способ все еще полезен в случае MVVM или нет, и какой лучший подход следует использовать с MVVM? Пожалуйста, предложите.

Ответы [ 2 ]

2 голосов
/ 14 марта 2020

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

Обычная практика - использовать шаблон репозитория, предложенный в Android Документация. Вот справочник по архитектуре: Android Справочник по компонентам архитектуры

Я разбил, какова роль каждого блока ниже:

Activity / Фрагмент : Здесь вы делаете все, что связано с вашими представлениями, например, инициализируете RecyclerView, демонстрируете диалоги, фрагментируете транзакции, показывает тосты et c. Здесь вы также зарегистрируете Observers для MutableLiveData (который присутствует в вашей ViewModel)

ViewModel : ViewModel содержит все бизнес-логи c, которые относятся к представлению , ViewModel не несет ответственности за инициализацию вызовов API. Причина в том, что, возможно, может возникнуть сценарий, когда вам потребуется дополнительная обработка ответа и, возможно, его сохранение в БД или даже выборка данных из БД в случае ошибки в API.

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

Репозиторий : Обычно здесь выполняются все сетевые операции и операции с базой данных. Это учитывает ответственность за выборку всех данных, которые должны быть отделены от ViewModel.

Вот краткий краткий пример

class UserViewModel(private val imageRepository) : ViewModel() {

    //Not required since you're using a Single which uses a SingleObserver that  doesn't require to be disposed manually.
    private val cd = CompositeDisposable() 

    val responseImages = MutableLiveData<ResponseImages>()
    val showError = MutableLiveData<Boolean>()

    fun getImages(text: String) =
        imageRepository.getImages(text)
                .observerOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe({
                    responseImages.value = (it)
                }, {
                    showError.value = true
                })


    override fun onCleared() {
        cd.dispose()
        super.onCleared()
    }

    fun callCleared() {
        onCleared()
    }
}

//Note: you should ideally just pass the API instance. unless required. 
class ImageRepository(val retrofitHelper: RetrofitHelper){

    fun getImages(text:String): Single<ResponseImages> {
        return retrofitHelper.apiInstance.getImages(Site.Method,Site.key,text)
    }

}

//In your Activities onCreate()

class HomeActivity: AppCompatActivity(){

    override fun onCreate(bundle: SavedInstanceState?){
        viewModel.responseImages.observer(this,Observer {
            //do something with your ResponseImages
        }
    }
}

Есть и другие вещи, которые можно сделать, например, использовать шаблон стратегии для своего репозитория, где ImageRepository является интерфейсом, а ImageRepositoryImpl содержит все подробности. и др c. Но это в другой раз!

SunflowerApp от Google - отличный справочник:)

0 голосов
/ 13 апреля 2020

Вы можете вызывать запросы API в классе репозитория для шаблона mvvm. Вы можете сослаться на это здесь .

...