代码之家  ›  专栏  ›  技术社区  ›  Kevin Ramirez Zavalza

改装使用存储的响应值处理多个调用

  •  1
  • Kevin Ramirez Zavalza  · 技术社区  · 7 年前

    我这里有一个关于Android和改型的新问题。我想知道在一个Android活动上处理多个异步调用的正确方法是什么,每个异步调用,onResponse都会返回下一个调用使用的值,因为如果我理解得很好,调用会在后台运行,这意味着如果调用没有完成,则返回的值将为null,直到您得到成功的响应。

    我想通过这样的方式来实现这一目标(仅限于基础):

    private List<SomeModel> mylist;
    final Call<List<SomeModel>> call1 = client.getSomeValues1();
    final Call<List<SomeModel2>> call2 = client.getSomeValues2();
    
    call1.enqueue(new Callback<SomeModel>() {
                        @Override
                        public void onResponse(SomeModel> call, Response<SomeModel> response) {
                            if (response.isSuccessful()) {
                                // Set mylist to response.body()
                                mylist = response.body();
                            } 
                        }
    
                        @Override
                        public void onFailure(Call<SomeModel> call, Throwable t) {
                            mylist = null;
                        }
                    });
    
    
    call2.enqueue(new Callback<SomeModel2>() {
                        @Override
                        public void onResponse(SomeModel2> call, Response<SomeModel2> response) {
                            if (response.isSuccessful()) {
                                // Do something with my list and also with call2 response
    
                                if(mylist != null) {
                                    for (SomeModel singleObject: mylist) {
                                        // Do something with each object
                                    }
                                }
    
                            } 
                        }
    
                        @Override
                        public void onFailure(Call<SomeModel2> call, Throwable t) {
                            // Do something with fail call
                        }
                    });
    

    与前面的示例类似,因为调用是在后台运行的,可能call2首先完成,然后mylist值将为null,因为call1尚未完成。

    我还想把call2放在call1-onResponse中,但我觉得这不对。我得说我还在学习,我是个新手。

    那么,正确的处理方法是什么?谢谢我希望我的问题可以理解。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Kevin Ramirez Zavalza    7 年前

    感谢您的建议@insa\U c 我用RXJava2实现了这一点,下面是我如何用一般方式解释的:

    首先,您需要将api服务定义为可观察的

    @GET("url-1/")
    Observable<List<Model1>> service1();
    
    @GET("url-2/")
    Observable<List<Model2>> service2();
    

    现在,在您的活动中,按以下方式拨打电话:

    final Observable<List<Model1>> call1 = APIClient.getClient().create(APIService.class).service1();
    
    final Observable<List<Model2>> call2 = APIClient.getClient().create(APIService.class).service2();
    

    现在,让我们使用zip创建一个唯一的可观察对象(我使用了一个列表,因为我正在向列表中添加两种不同类型的对象,当两个调用都完成时,我将得到这两种对象):

    <Observable<List<Object>> test = Observable.zip(call1, call2, new BiFunction<List<Model1>, List<Model2>, List<Object>>() {
        @Override
        public List<Object> apply(List<Model1> objects1, List<Model2> objects2) throws Exception {
            List<Object> list = new ArrayList<>();
            list.addAll(objects1);
            list.addAll(objects2);
            return list;
        }
    }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    

    现在唯一要做的就是订阅并决定要对这两个响应的内容做什么:

    test.subscribe(new Observer<List<?>>() {
    
        @Override
        public void onSubscribe(Disposable d) {
            Log.d("TAG", "onSubscribe");
        }
    
        @Override
        public void onNext(List<?> objects) {
            // You can split the list by object in here with an instanceof to determine if it's Model1 or Model2
        }
    
        @Override
        public void onError(Throwable e) {
            e.printStackTrace();
        }
    
        @Override
        public void onComplete() {
            // Do something here, both calls finished, if you stored something in onNext method you can use it here.
        }
    
    });
    

    我希望这些信息能对某人有所帮助。