【问题标题】:Retrofit handle multiple calls with response value stored an reused改造处理多个调用,响应值存储并重用
【发布时间】:2018-01-23 22:24:13
【问题描述】:

我有一个关于 Android 和 Retrofit 的新问题。我想知道在 Android Activity 上处理多个异步调用的正确方法是什么,每一个,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 中,但我觉得不对。不得不说,我还在学习中,我还挺菜鸟的。

那么,处理这个问题的正确原因是什么以及如何处理?谢谢。我希望我的问题可以理解。

【问题讨论】:

标签: android retrofit2


【解决方案1】:

感谢您的建议@insa_c 我使用 RXJava2 实现了这一点,以下是我如何解释它的一般方式:

首先你需要将你的 api 服务定义为 Observables

@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,因为我将两种不同类型的对象添加到列表中,当两个调用完成时我会得到):

<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.
    }

});

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-27
    • 1970-01-01
    • 2020-09-15
    • 2014-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多