这是我的应用中的流量数据:
在视图中,我将方法onClick称为presenter.Method()。在presenter上的此方法中,我将调用传递给model(Model拥有自己的抽象层-> interface modelHelper。它通过Conctructor Presenter中的匕首2注入)。
在模型中,我得到了用于网络调用的方法:
@Override
public void networkCallForData(String request) {
request = "volumes?q=" + request;
compositeDisposable.add(
api.getBook(request)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
books -> {
items.clear();
items.addAll(books.items);
}
, Throwable::printStackTrace
, () -> {
}
)
);
}
}
我有2个问题: 1.在MVP体系结构中,模型层是否应该注入抽象演示者的实例并将其连接到模型,就像使用view一样?如果不是,我应该如何将数据从模型发送到演示者?
private List<Items> items = new ArrayList<>();
和获取方法:
public Observable<List<Items>> getItemsObservable() {
return itemsObservable;
}
在这里我创建可观察的:
private Observable<List<Items>> itemsObservable = Observable.fromArray(items);
在主持人中,我得到了:
private void getDataFromModel() {
compositeDisposable.add(
findActivityModel.getItemsObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
books -> {
view.setRecycler(books);
}, Throwable::printStackTrace
, () -> {
view.setRecyclerVisible();
}
)
);
}
}
当我单击按钮进行搜索时,我得到了第一个空响应,因为我在列表上观察到尚未更新(通过网络调用方法进行更新)。如果我第二次按下按钮,这就是我从1个请求中获取数据的时间。我应该如何链接来自不同类的那两个RxJava方法?
答案 0 :(得分:0)
1。在MVP体系结构中,模型层是否应该注入抽象演示者的实例并将其连接到模型,就像使用视图一样?
不。模型层不应直接访问视图层或表示层。
还要注意,将.observeOn(AndroidSchedulers.mainThread())
放在模型层的任何实现中都没有多大意义。
如果不是,我应该如何将数据从模型发送到演示者?
模型应仅响应演示者的查询。这可能是一个简单的函数调用。模型不需要保存Presenter实例即可处理。
2。 ...我应该如何链接来自不同类的那两个RxJava方法?
考虑此实现:
模型
@Override
public Observable<List<Items>> networkCallForData(String request) {
request = "volumes?q=" + request;
return api.getBook(request);
}
演示者
// 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
。
演示者
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()
返回一个可观察的对象,该对象一次发出一个数组项。因此,在这种情况下,它不是很有用。
似乎您有一个对象以及包裹该对象的可观察对象。如果您将这两件事放在同一个地方,通常表示设计不好。
私人可观察> 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);
}