Слияние и фильтрация результатов (RX_observables) из независимого источника - PullRequest
0 голосов
/ 05 ноября 2018

Привет всем и всем привет!

У меня есть два независимых источника API (lastFM и iTune). Код работает для ich отдельно, и я могу искать (фильтровать) художника, которого я хочу. Теперь я хочу объединить результаты, используя для этого подхода RXJava, и показать их в RecyclerView.

Я читал о Observable.zip или простом слиянии (порядок не важен), но я слишком долго занимался этой проблемой, и я не знал, с чего начать. Должен ли я создать следующую модель для комбайна, например:

public class iTuneAndLastFM {

    public JsonArray iTuneObject;
    public JsonArray LastFmObject;

    public iTuneAndLastFM(JsonArray iTuneObject, JsonArray lastFmObject) {
        this.iTuneObject = iTuneObject;
        LastFmObject = lastFmObject;
    }
}

или в этом нет необходимости? Я застрял здесь, и я не могу двигаться .. так что помогите!

моя текущая работа (ситуация):

public interface ServiceItune

String API_ITUNE_BASE_FULL_URL = "https://itunes.apple.com/search";
        @GET
        Observable<RootiTune> getItuneArtistNameRx2NoList(
                @Url String url,
                @Query("term") String artisName);

public interface ServiceLastFm

String API_LAST_FM_FULL_URL = "http://ws.audioscrobbler.com/2.0/?method=artist.search&format=json";

    Observable<RootLastFm> searchArtistRx(
            @Url String url,
            @Query("artist") String artistName,
            @Query("api_key") String key
    );

моя ViewModel:

public void getLastFmRx(String query) {
    disposables.add(serviceLastFm.searchArtistRx(ServiceLastFm.API_LAST_FM_FULL_URL, query,ServiceLastFm.KEY_LAST_FM)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(rootLastFmList -> responseLiveData.setValue(rootLastFmList))
            );
};
public  void getItubnRxTest2 (String query){
    disposables.add(serviceItune.getItuneArtistNameRx2NoList(ServiceItune.API_ITUNE_BASE_FULL_URL,query)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(rootiTuneList->responsItuneeLiveData.setValue(rootiTuneList) )
    );
};

и последнее, мой модель iTunes :

@AutoValue
public abstract class  RootiTune {

    public static TypeAdapter<RootiTune> typeAdapter(Gson gson){
        return new AutoValue_RootiTune.GsonTypeAdapter(gson);
    }
    @Nullable
    @SerializedName("resultCount")
    public abstract Integer getListSize();

    @Nullable
    @SerializedName("results")
    public abstract List<ResultiTune> getListSongs();

    @Nullable
    @SerializedName("errorMessage")
    public abstract String getErrorMessage();

}

и LastFM модель :

public class RootLastFm {
    @Expose
    private Results results;
    public List<ArtistLastFm> getListOfLastFm;
    public Results getResults() {
        return results;
    }
    public void setResults(Results results) {
        this.results = results;
    }
}

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Вы можете сделать что-то вроде этого,

Observable<RootiTune> ituneObservable = serviceItune
        .getItuneArtistNameRx2NoList(ServiceItune.API_ITUNE_BASE_FULL_URL, query);
Observable<RootLastFm> lastFmObservable = serviceLastFm
        .searchArtistRx(ServiceLastFm.API_LAST_FM_FULL_URL, query, ServiceLastFm.KEY_LAST_FM);
Observable
    .zip(
        ituneObservable,
        lastFmObservable,
        (BiFunction<RootiTune, RootLastFm, Pair<RootiTune, RootLastFm>>) (ituneResult, lastFmResult) -> Pair
             .create(ituneResult, lastFmResult)
        )
        .toList()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
            list -> listOfPair,
            error -> {
                // TODO handle error
            }
        );

Как только вы получите список Pair, прокрутите список и выполните

pair.first to get RootiTune
pair.second to get RootLastFm
0 голосов
/ 05 ноября 2018

Если у вас нет базового интерфейса для RootiTune и RootLastFm, вы можете использовать Observable#zip(). Прежде всего, создайте оболочку для двух результатов:

class ResultWrapper(RootiTune ituneResult, RootLastFm lastFmResult) {
    public final RootiTune ituneResult;
    public final RootLastFm lastFmResult;

    public ResultWrapper(RootiTune ituneResult, RootLastFm lastFmResult) {
        this.ituneResult = ituneResult;
        this.lastFmResult = lastFmResult;
    }
}

После этого вы можете архивировать источники:

Observable<RootiTune> ituneObservable = serviceItune.getItuneArtistNameRx2NoList(ServiceItune.API_ITUNE_BASE_FULL_URL,query);
Observable<RootLastFm> lastFmObservable = serviceLastFm.searchArtistRx(ServiceLastFm.API_LAST_FM_FULL_URL, query,ServiceLastFm.KEY_LAST_FM);
Observable.zip(ituneObservable, lastFmObservable, (ituneResult, lastFmResult) -> new ResultWrapper(ituneResult, lastFmResult))
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(resultWrapper -> {
            responseFmLiveData.setValue(resultWrapper.lastFmResult);
            responsItuneeLiveData.setValue(resultWrapper.ituneResult);
        }, 
        error -> {
            // TODO handle error
        });
...