如何使用 RxJava 获取 map 函数返回的结果?
How can I get the results returned by a map function with RxJava?
我正在使用 RxJava 的 map
函数从响应 JSON 创建图像 URL 列表,作为我 API 调用的一部分,我正在获取多媒体信息列表。如何处理 map 函数返回的列表?这是我的代码:
BrowseAPI service = CKApplication.getInstance().getRestAdapter().create(BrowseAPI.class);
BrowseRequest request = new BrowseRequest("0","50","true","A");
service.getMultmedia(MyApplication.getInstance().getJSessionID(), request).map(new Func1<Multimedia, Object>() {
@Override
public Object call(Multimedia multimedia) {
ArrayList<String> imageURLs = new ArrayList<String>();
for(MultiMediaImage image : multimedia.getResultsWrapper().getMultiMediaImage()) {
String url = "https://xxxxxxx/service/content/imageByEntitlement/";
url += image.getEid();
url +="?thumbnail=true";
imageURLs.add(url);
}
return imageURLs;
}
}).subscribe(multimedia -> {
Log.d("dfa", "adga");
});
我可以根据响应创建 URL 字符串列表,我想在单独的 activity 或片段中处理此 URL 列表。
使用flatMap
,我相信这可以改进:
BrowseAPI service = CKApplication.getInstance().getRestAdapter().create(BrowseAPI.class);
BrowseRequest request = new BrowseRequest("0","50","true","A");
service.getMultmedia(CKApplication.getInstance().getJSessionID(), request).flatMap(new Func1<Multimedia, Observable<MultiMediaImage>>() {
@Override
public Observable<MultiMediaImage> call(Multimedia multimedia) {
Observable<MultiMediaImage> observable = Observable.from(multimedia.getResultsWrapper().getMultiMediaImage());
return observable;
}
}).subscribe(new Action1<MultiMediaImage>() {
@Override
public void call(MultiMediaImage multiMediaImage) {
service.getImageObject(CKApplication.getInstance().getJSessionID(), multiMediaImage.getEid()).observeOn(AndroidSchedulers.mainThread()).subscribe(imageObject -> {
mImages.add(imageObject.getAuthenticatedStoreUrl());
adapter.notifyDataSetChanged();
});
}
});
这个怎么样?
Observable<Multimedia> multimediaObservable = service.getMultmedia(MyApplication.getInstance().getJSessionID(), request);
Subscription subscription = bindFragment(this, multimediaObservable
.observeOn(AndroidSchedulers.handlerThread(new Handler()))
.map(new Func1<Multimedia, ArrayList<String>>() {
@Override
public ArrayList<String> call(Multimedia multimedia) {
ArrayList<String> imageURLs = new ArrayList<String>();
for(MultiMediaImage image : multimedia.getResultsWrapper().getMultiMediaImage()) {
imageURLs.add(makeImageUrl(image);
}
return imageURLs;
}
})).subscribe(multimediaArrayList -> {
//do something with the list
});
...
private String makeImageUrl(MultiMediaImage image){
String url = "https://xxxxxxx/service/content/"
url += image.getEid();
url +="?thumbnail=true";
return url;
}
或者使用您在 subscribe() 方法中使用的 Java8 语法:
.map(multimedia -> {
ArrayList<String> imageURLs = new ArrayList<String>();
for(MultiMediaImage image : multimedia.getResultsWrapper().getMultiMediaImage()) {
imageURLs.add(makeImageUrl(image);
}
return imageURLs;
})
一些注意事项:
我假设 multimediaObservable 是一个不应在主线程中完成的网络调用。如果它是从 Retrofit 发出的可观察对象,则您无需担心有单独的异步线程。
bindFragment() 是 RxAndroid 库的一部分,它会自动
"observe(s)On" mainThread()。对于活动使用 bindActivity()。或者使用 observeOn(mainThread()).
不需要像第二个例子那样使用平面图,因为它不需要对象就可以转换为可观察对象并返回普通对象(地图可以直接接收)。
不要忘记subsribe()中的onError。
更新:
您可以使用 from()
来展开数组并处理订阅中的每个 MultimediaImage 项目。
Subscription subscription = bindFragment(this, multimediaObservable
.observeOn(AndroidSchedulers.handlerThread(new Handler()))
.flatMap(multimedia->
Observable.from(multimedia.getResultsWrapper().getMultiMediaImage())
).subscribe(multimediaImage -> {
//multimediaImage is a MultimediaImage class object
Log.i("ImageId", multimediaImage.getEid());
});
我正在使用 RxJava 的 map
函数从响应 JSON 创建图像 URL 列表,作为我 API 调用的一部分,我正在获取多媒体信息列表。如何处理 map 函数返回的列表?这是我的代码:
BrowseAPI service = CKApplication.getInstance().getRestAdapter().create(BrowseAPI.class);
BrowseRequest request = new BrowseRequest("0","50","true","A");
service.getMultmedia(MyApplication.getInstance().getJSessionID(), request).map(new Func1<Multimedia, Object>() {
@Override
public Object call(Multimedia multimedia) {
ArrayList<String> imageURLs = new ArrayList<String>();
for(MultiMediaImage image : multimedia.getResultsWrapper().getMultiMediaImage()) {
String url = "https://xxxxxxx/service/content/imageByEntitlement/";
url += image.getEid();
url +="?thumbnail=true";
imageURLs.add(url);
}
return imageURLs;
}
}).subscribe(multimedia -> {
Log.d("dfa", "adga");
});
我可以根据响应创建 URL 字符串列表,我想在单独的 activity 或片段中处理此 URL 列表。
使用flatMap
,我相信这可以改进:
BrowseAPI service = CKApplication.getInstance().getRestAdapter().create(BrowseAPI.class);
BrowseRequest request = new BrowseRequest("0","50","true","A");
service.getMultmedia(CKApplication.getInstance().getJSessionID(), request).flatMap(new Func1<Multimedia, Observable<MultiMediaImage>>() {
@Override
public Observable<MultiMediaImage> call(Multimedia multimedia) {
Observable<MultiMediaImage> observable = Observable.from(multimedia.getResultsWrapper().getMultiMediaImage());
return observable;
}
}).subscribe(new Action1<MultiMediaImage>() {
@Override
public void call(MultiMediaImage multiMediaImage) {
service.getImageObject(CKApplication.getInstance().getJSessionID(), multiMediaImage.getEid()).observeOn(AndroidSchedulers.mainThread()).subscribe(imageObject -> {
mImages.add(imageObject.getAuthenticatedStoreUrl());
adapter.notifyDataSetChanged();
});
}
});
这个怎么样?
Observable<Multimedia> multimediaObservable = service.getMultmedia(MyApplication.getInstance().getJSessionID(), request);
Subscription subscription = bindFragment(this, multimediaObservable
.observeOn(AndroidSchedulers.handlerThread(new Handler()))
.map(new Func1<Multimedia, ArrayList<String>>() {
@Override
public ArrayList<String> call(Multimedia multimedia) {
ArrayList<String> imageURLs = new ArrayList<String>();
for(MultiMediaImage image : multimedia.getResultsWrapper().getMultiMediaImage()) {
imageURLs.add(makeImageUrl(image);
}
return imageURLs;
}
})).subscribe(multimediaArrayList -> {
//do something with the list
});
...
private String makeImageUrl(MultiMediaImage image){
String url = "https://xxxxxxx/service/content/"
url += image.getEid();
url +="?thumbnail=true";
return url;
}
或者使用您在 subscribe() 方法中使用的 Java8 语法:
.map(multimedia -> {
ArrayList<String> imageURLs = new ArrayList<String>();
for(MultiMediaImage image : multimedia.getResultsWrapper().getMultiMediaImage()) {
imageURLs.add(makeImageUrl(image);
}
return imageURLs;
})
一些注意事项:
我假设 multimediaObservable 是一个不应在主线程中完成的网络调用。如果它是从 Retrofit 发出的可观察对象,则您无需担心有单独的异步线程。
bindFragment() 是 RxAndroid 库的一部分,它会自动 "observe(s)On" mainThread()。对于活动使用 bindActivity()。或者使用 observeOn(mainThread()).
不需要像第二个例子那样使用平面图,因为它不需要对象就可以转换为可观察对象并返回普通对象(地图可以直接接收)。
不要忘记subsribe()中的onError。
更新:
您可以使用 from()
来展开数组并处理订阅中的每个 MultimediaImage 项目。
Subscription subscription = bindFragment(this, multimediaObservable
.observeOn(AndroidSchedulers.handlerThread(new Handler()))
.flatMap(multimedia->
Observable.from(multimedia.getResultsWrapper().getMultiMediaImage())
).subscribe(multimediaImage -> {
//multimediaImage is a MultimediaImage class object
Log.i("ImageId", multimediaImage.getEid());
});