首页 > 解决方案 > 组合请求时使用 Retrofit2 和 RxJava2 调用 web 服务后执行方法的问题

问题描述

我继续我的问题:我想进行网络服务调用(三个调用),对接收到的数据执行一些操作,最后更新 UI(许多文本视图)。我使用 retrofit2 和 rxjava2 来执行 web 服务调用,特别是 Observable.zip() 对三个 web 服务进行一次调用,以便在执行一些计算之前获得所有三个数据。webservice调用运行良好,但我注意到并不是我的计算方法(onComplete)中的所有指令都被调用,只有第一个textView.setText()被调用,之后的所有指令都没有被执行。即使我只用 Log.i 填充方法,也不会调用所有方法。当我将方法放入 onNext() 时也会发生同样的情况,不会引发错误。我做错了什么?这是我的代码:

// 网络服务

@GET("url 1")
Observable<List<Data1>> getData1();

@GET("url 2")
Observable<List<Data2>> getData2();

@GET("url 3")
Observable<List<Data3>> getData3();

//主要活动

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //getTextViews
    getData();
}

private void getData(){
    Retrofit retrofit = Retrofit.Builder()
            .baseUrl("apiURL")
            .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
            .client(httpClient.build())
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build();
    WebService service = retrofit.create(WebService.class);
    Observable.zip(service.getData1(), service.getData2(), service.getData3(), new Function3<List<Data1>, List<Data2>, List<Data3>, MergedResponse>() {
        int i;
        @Override
        public MergedResponse apply(List<Data1> data1, List<Data2> data2, List<Data3> data3) throws Exception {
            return new MergedResponse(data1, data2, data3);
        }
    }).subscribe(new Observer<MergedResponse>() {
        @Override
        public void onSubscribe(Disposable d) {

        }

        @Override
        public void onNext(MergedResponse mergedResponse) {
            // dispatch my merged data
        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onComplete() {
            computeReceivedData();
        }
    });
}

private void computeReceivedData(){
   // List of expressions to compute data and update the view (textview)
    ...
    textView1.setText()
    textView2.setText()
    ...
   // Only the first expression textView1.setText() here is called.If I put it at the begining of the method, it stop after executing it
}

改造和 rxjava2 vresion

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.9.0'
implementation "com.squareup.retrofit2:adapter-rxjava2:2.9.0"
implementation 'io.reactivex.rxjava2:rxjava:2.2.2'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.legacy:legacy-support-v13:1.0.0'

标签: androidretrofit2rx-java2rx-android

解决方案


我认为,您正在尝试使用 MainThread 从后台线程更新 UI。

因此,您必须在代码中添加以下行

.subscribeOn(Schedulers.io()) // will do operation on background thread
.observeOn(AndroidSchedulers.mainThread()) // will notify UI for changes

前任。

Observable.zip(service.getData1(), service.getData2(), service.getData3(), new Function3<List<Data1>, List<Data2>, List<Data3>, MergedResponse>() {
        int i;

        @Override
        public MergedResponse apply(List<Data1> data1, List<Data2> data2, List<Data3> data3) throws Exception {
            return new MergedResponse(data1, data2, data3);
        }
    }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<MergedResponse>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(MergedResponse mergedResponse) {
                    // dispatch my merged data
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {
                    computeReceivedData();
                }
            });

推荐阅读