我在Android中玩RxJava。 我试图从服务器获取地点的响应。一切正常:
这是我的Retrofit界面:
@GET("/some/path")
Observable<Response> search(@QueryMap Map map);
以下是我处理这个问题的方法:
endpointService.search(requestMap)
.onErrorReturn(throwable -> {
L.e(TAG, "problems");
return null;
})
.subscribe(rxBus::send);
正如您所看到的,我将一个事件(RxBus)发布给感兴趣的各方,在这种情况下,是一个片段:
rxBus.register(Response.class)
.subscribe(event -> {
L.d(TAG, "Received search response");
});
现在它有效。我不是,这个&#34;想法&#34;处理REST调用在灾难中不会完成(我是RxJava的新手),但是现在它看起来还不错......
无论如何 - 这种反应是巨大的。我只需要一个名单和地址列表。这个响应给了我一个带有大量附加数据的huuuge JSON。
我的想法是使用map
(或flatMap
更改此设置,我仍然遇到了解差异的问题)。
我实现了像
.map(event -> {
List<SearchItem> list = new ArrayList<>();
for (Response r : event.getItems) {
list.add(new Item(r.getName, r.getAddress));
}
return list;
}
)
它确实有效,但是我不确定前期是否也不过“老了”#34; IDE说我不能使用collect call
但是我从未使用它,而且自动更正会使事情变得更糟:)
所以 - 我是以正确的方式处理这整件事吗?
编辑:
我修改了我的代码:
rxBus.register(Response.class)
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.map(event -> event.getResponse().getList())
.flatMap(Observable::from)
.map(v -> new SearchItem(v.getName(), v.getAddress())
.toList()
.subscribe(event -> {
L.w(TAG, "Stuff happens");
});
我不知道发生了什么,但此代码不再有效。好吧。如果没有.toList()
,它会多次启动Log。然而 - 没有任何反应。我做错了吗?
答案 0 :(得分:2)
我认为一般方法很好。您可以通过以下方式稍微改善项目的处理:
...
.map(Event::getItems)
.flatMap(Observable::from)
.map(response -> new Item(response.getName(), response.getAddress()))
.toList()
...
我假设您使用retrolambda。在这种情况下,IDE建议(“收集”)是将Java 8 Streams API语法应用于for循环,这在Android中不起作用。
修改强>
我没有意识到第一个选项对于永远不会发出onCompleted
事件的热可观察案例不起作用,toList()
运算符需要该事件知道何时停止组装列表。< / p>
感谢@ david.mihola,这种情况有不同的选择:
...
.flatMap(event -> Observable.from(event.getResponse().getList())
.map(item -> new SearchItem(v.getName(), v.getAddress()))
.toList())
...