1.В архитектуре MVP, должен ли слой Model внедрить экземпляр абстрагированного презентатора и подключить его к модели, как в представлении?
Нет.Слой модели не должен иметь прямого доступа к слою просмотра или представления.Также обратите внимание, что не имеет смысла помещать .observeOn(AndroidSchedulers.mainThread())
в любую реализацию уровня модели.
, если нет, то как я должен отправлять данные из модели в презентатор?
Модель должна просто отвечать на запросы докладчиков.Это может быть простой вызов функции.Для обработки модели не требуется хранить экземпляры Presenter.
2.... Как мне связать эти два метода RxJava из другого класса?
Рассмотрим эту реализацию:
Модель
@Override
public Observable<List<Items>> networkCallForData(String request) {
request = "volumes?q=" + request;
return api.getBook(request);
}
Presenter
// Call this once in the beginning.
private void getDataFromModel() {
compositeDisposable.add(
findActivityModel.networkCallForData(request)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
books -> {
view.setRecycler(books);
}, Throwable::printStackTrace
, () -> {
view.setRecyclerVisible();
}
)
);
}
Вышеприведенной реализации должно быть достаточно, если вы получаете данные только один раз за экран.Но вы упомянули что-то вроде кнопки обновления.Для этого вы можете использовать BehaviorSubject
или BehaviorProcessor
.
Presenter
private BehaviorSubject<List<Item>> items =
BehaviorSubject.create(); // You may move this line to the Model layer.
// Call this once in the beginning to setup the recycler view.
private void getDataFromModel() {
// Instead of subscribing to Model, subscribe to BehaviorSubject.
compositeDisposable.add(
items.subscribe(books -> {
// Any change in BehaviorSubject should be notified
view.setRecycler(books);
view.setRecyclerVisible();
});
}
// Trigger this on button clicks
private void refreshData() {
compositeDisposable.add(
findActivityModel.networkCallForData(request)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(books -> {
// Refresh BehaviorSubject
items.onNext(books);
});
}
Даже это может не совсем соответствовать вашим потребностям, но надеюсь, что вы получитеидея.Кроме того, несколько примечаний:
Observable.fromArray()
возвращает наблюдаемое, которое испускает элементы массива по одному за раз.Поэтому в этом сценарии это не очень полезно.
Кажется, у вас есть объект и наблюдаемое, которое оборачивает объект.Если эти две вещи находятся в одном и том же месте, это обычно является признаком плохого дизайна.
private Observable> itemsObservable;приватные элементы списка;
Это неправильный способ использовать наблюдаемые, но также нарушает единый источник правды.Один из возможных способов рефакторинга это:
private BehaviorSubject<List<Items>> itemsObservable;
// private List<Items> items; // Remove this line
public Observable<List<Items>> getItemsObservable() {
return itemsObservable.hide();
}
// Call this whenever you need to update itemsObservable
private void updateItems(List<Item> newItems) {
itemsObservable.onNext(newItems);
}