【问题标题】:How can I return value from function onResponse of Retrofit?如何从 Retrofit 的 onResponse 函数返回值?
【发布时间】:2015-12-09 16:36:18
【问题描述】:

我试图在retrofit 调用请求中返回一个从onResponse 方法获得的值,有没有办法从被覆盖的方法中获取该值?这是我的代码:

public JSONArray RequestGR(LatLng start, LatLng end)
    {
       final JSONArray jsonArray_GR;

        EndpointInterface loginService = ServiceAuthGenerator.createService(EndpointInterface.class);    
        Call<GR> call = loginService.getroutedriver();
        call.enqueue(new Callback<GR>() {
            @Override
            public void onResponse(Response<GR> response , Retrofit retrofit)
            {

                 jsonArray_GR = response.body().getRoutes();
//i need to return this jsonArray_GR in my RequestGR method
            }
            @Override
            public void onFailure(Throwable t) {
            }
        });
        return jsonArray_GR;
    }

我无法获得jsonArray_GR 的值,因为要能够在onResponse 方法中使用它,我需要将它声明为最终值,并且我不能给它一个值。

【问题讨论】:

    标签: java json methods retrofit


    【解决方案1】:

    问题是你试图同步返回enqueue 的值,但它是一个使用回调的异步方法,所以你不能这样做。你有两个选择:

    1. 您可以将RequestGR 方法更改为接受回调,然后将enqueue 回调链接到它。这类似于 rxJava 等框架中的映射。

    这大概是这样的:

    public void RequestGR(LatLng start, LatLng end, final Callback<JSONArray> arrayCallback)
        {
    
            EndpointInterface loginService = ServiceAuthGenerator.createService(EndpointInterface.class);    
            Call<GR> call = loginService.getroutedriver();
            call.enqueue(new Callback<GR>() {
                @Override
                public void onResponse(Response<GR> response , Retrofit retrofit)
                {
    
                     JSONArray jsonArray_GR = response.body().getRoutes();
                     arrayCallback.onResponse(jsonArray_GR);
                }
                @Override
                public void onFailure(Throwable t) {
                   // error handling? arrayCallback.onFailure(t)?
                }
            });
        }
    

    这种方法的注意事项是它只是将异步的东西推到了另一个层次,这对你来说可能是个问题。

    1. 您可以使用类似于BlockingQueuePromiseObservable 的对象,甚至可以使用您自己的容器对象(注意线程安全),以便检查和设置值。

    这看起来像:

    public BlockingQueue<JSONArray> RequestGR(LatLng start, LatLng end)
        {
            // You can create a final container object outside of your callback and then pass in your value to it from inside the callback.
            final BlockingQueue<JSONArray> blockingQueue = new ArrayBlockingQueue<>(1);
            EndpointInterface loginService = ServiceAuthGenerator.createService(EndpointInterface.class);    
            Call<GR> call = loginService.getroutedriver();
            call.enqueue(new Callback<GR>() {
                @Override
                public void onResponse(Response<GR> response , Retrofit retrofit)
                {
    
                     JSONArray jsonArray_GR = response.body().getRoutes();
                     blockingQueue.add(jsonArray_GR);
                }
                @Override
                public void onFailure(Throwable t) {
                }
            });
            return blockingQueue;
        }
    

    然后您可以像这样在调用方法中同步等待您的结果:

    BlockingQueue<JSONArray> result = RequestGR(42,42);
    JSONArray value = result.take(); // this will block your thread
    

    我强烈建议阅读 rxJava 之类的框架。

    【讨论】:

    • 我无法在改造 2.0 中使用该解决方案。 @torbinksy 你能帮帮我吗?
    • @wanz 我无法让它与 rf 2.0 一起使用...如果/当我得到一个可行的解决方案时会通知你
    • @JC23 非常感谢您的帮助,我之前问过有人回答过stackoverflow.com/a/37142046/4226651 但我仍然不知道如何使用它
    • Callback对象的封装是什么?
    • 它在 onresponse 触发之前返回,所以总是得到空响应
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 1970-01-01
    • 2018-09-17
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多