【问题标题】:How chain Retrofit calls?链改造如何调用?
【发布时间】:2016-04-17 11:37:55
【问题描述】:

如何进行一次又一次的改造 2 调用?

我正在阅读有关 RxJava 的信息,并且已经在使用 RxJava 进行调用,但我还没有找到一个很好的例子来说明如何使用 flatMaps。

有人可以向我解释一下怎么做吗?

我正在尝试进行这两个调用,在它们都完成后,我想开始一个新的活动。

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    Retrofit retrofit = new Retrofit.Builder()
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl("http://api.openweathermap.org/data/2.5/")
            .build();

    WeatherService weatherService = retrofit.create(WeatherService.class);
    final Observable<Weather> london = weatherService.getCurrent();

    london.subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<Weather>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(Weather weather) {

                    Log.i("WEATHER","Weather Name: " + weather.getName());


                }
            });

    final Observable<Wind> windObservable = weatherService.getWind();
    windObservable.subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<Wind>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(Wind wind) {

                  Log.i("WEATHER","Wind: " + wind.getSpeed().toString());  

                }
            });

}


}

【问题讨论】:

  • 您确定要在这种情况下链接它们吗?使用Observable.combineLatest() 同时运行这些可能更谨慎。如果下一次调用依赖于上一次的输出,你真的只想用地图链接 observables

标签: android web-services retrofit rx-java observable


【解决方案1】:

也许这个链接:https://github.com/ReactiveX/RxJava/wiki/Combining-observables 会有所帮助。结帐拉链。最终 switchMap 方法在您的情况下可能很有用。

编辑: 也许这个例子http://joluet.github.io/blog/2014/07/07/rxjava-retrofit/ 会帮助你更多。

编辑#2:一些代码

login().switchMap(new Func1<FirstResponse, Observable<SecondResponse>>() {
            @Override
            public Observable<SecondResponse> call(FirstResponse t) {
                if (ApiUtils.isLoginValid(t)) {
                        return profile(t.getToken());
                    }
                    else{
                        return Observable.error(new CustomException());
                    }
                }

            }
        }).subscribe(subscriber());

注意:配置文件方法返回类型是Observable&lt;SecondResponse&gt;,订阅者方法类型是Subscriber&lt;? super SecondResponse&gt;

【讨论】:

  • 我已经尝试按照示例进行操作,但没有得到它,如何将第二次调用设置为在第一次调用之后发生?我是否需要使用普通的 Observable 设置调用,然后在 flatMap 中调用它们?
  • 那就用switchMap吧。从第一个可观察的创建 switchMap 到“第二次改造调用的可观察”。几天前我做了这样的东西,效果很好。
  • 我怎么做这个?我对 RxJava 很陌生,我基本上一无所知,代码示例会很有帮助。
  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
  • @AbhinavSinghMaurya & for dovnwoter 我打算在下班后用代码更新我的答案。
【解决方案2】:

您可以像示例中那样使用flatMap,也可以使用concatWith

static Observable<Integer> intObservable() {
    return Observable.just(1).delay(1, TimeUnit.SECONDS);
}

static Observable<String> stringObservable() {
    return Observable.interval(1, TimeUnit.SECONDS).take(2).map(v -> v.toString());
}

public static void main(String[] args) {
    intObservable()
        .doOnNext(System.out::println)
        .ignoreElements()
        .cast(Object.class)
    .concatWith(stringObservable()
            .doOnNext(System.out::println)
            .ignoreElements())
    .toBlocking()
    .subscribe();
}

但是,如果两个来源具有不同的类型,您需要进行一些转换。

【讨论】:

  • 我已经在我试图做的两个调用中添加了一些代码,所以我需要在你的例子中创建一个新的 observable,比如 intObservable() 并调用第二个 Observable,在我的例子中是 windObservable .concatWith() 中的 ()?还有一个问题,使用 concatWith,我可以拨打多少次电话,一个接一个?
  • 在我的示例中,您可以使用london 代替intObservablewind 而不是stringObservable
  • 所以我不需要设置 onCompleted()、onError()、onNext()、.subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) 的部分代码? .doOnNext 是我放置 Log.i("WEATHER","Weather Name: " + weather.getName()); 的地方。例如?
  • 用你认为合适的副作用代码替换System.out::println
【解决方案3】:

您有多种选择。其中之一是使用zip

london.zipWith(weatherService, new Func2<Weather, Wind, Something>() {
    @Override
    public Something call(final Weather weather, final Wind wind) {
        ...
        return something;
    }
}).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<Something>() {
    @Override
    public void onCompleted() {

    }

    @Override
    public void onError(final Throwable e) {

    }

    @Override
    public void onNext(final Something something) {

    }
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    • 2018-05-26
    • 2021-05-24
    • 2019-08-01
    • 2020-09-17
    • 2019-03-05
    相关资源
    最近更新 更多