3

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 の文字列リストを作成できます。この 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();
        });
    }
});
4

1 に答える 1

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() は、mainThread() を自動的に「監視」する RxAndroid ライブラリの一部です。アクティビティには bindActivity() を使用します。または、observeOn(mainThread()) を使用します。

  • 2 番目の例のように 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());
});
于 2015-05-30T20:19:27.437 に答える