如何通过RxJava获取map函数返回的结果?

时间:2015-05-08 17:04:13

标签: android retrofit rx-java rx-android

我使用RxJava的map函数获取API调用的多媒体信息列表,以便从响应JSON创建图像URL列表。如何从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的字符串列表,我想在单独的活动或片段中处理这个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();
        });
    }
});

1 个答案:

答案 0 :(得分:1)

这个怎么样?

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())。

  • 在第二个示例中没有必要使用flatmap,因为它无需将对象转换为可观察对象并返回到普通对象(地图可直接接收)。

  • 不要忘记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());
});