如何从Retrofit v2的onResponse返回值 [英] How can I return value from onResponse of Retrofit v2

查看:668
本文介绍了如何从Retrofit v2的onResponse返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从我的函数返回一个字符串值.但是我不知道该如何处理?我尝试了最终的单阵列解决方案,但没有成功.

I want to return a string value from my function. But I do not know how to handle it? I tried final one-array solution but it did not work out.

这是我的代码:

public String revealCourtPlace(String courtID)
{

    BaseService.getInstance().getUniqueCourt(Session.getToken(),courtID).enqueue(new Callback<JsonObject>()
    {
        @Override
        public void onResponse(Call<JsonObject> call, Response<JsonObject> response)
        {

            JsonObject object = response.body();
            boolean success = object.get("success").getAsBoolean(); //json objesinde dönen success alanı true ise
            if (success)
            {
                JsonArray resultArray = object.get("data").getAsJsonObject().get("result").getAsJsonArray();
                for (int i = 0; i < resultArray.size(); i++)
                {
                    JsonObject jsonInfoResult = resultArray.get(i).getAsJsonObject();
                    String courtName=jsonInfoResult.get("name").getAsString();
                }

            }

        }

        @Override
        public void onFailure(Call<JsonObject> call, Throwable t)
        {

        }

    });

    //return ?
}

推荐答案

onResponse是异步的,因此很可能在revealCourtPlace返回后完成.

onResponse is asynchronous so it will most probably finish after revealCourtPlace has returned.

您不能从onResponse内部返回任何内容.但是,您可以传递该值或重组代码以与Rx之类的东西一起使用.

You cannot return anything from inside onResponse like that. You can however, pass the value up or restructure your code to work with something like Rx.

让我解释一下.因此,一种选择是通过回调传递您想要的字符串值.假设您有以下界面:

Let me explain. So, one option is to pass the string value you want up with a callback. Say you have the interface:

public interface RevealCourtPlaceCallbacks {
     void onSuccess(@NonNull String value);

     void onError(@NonNull Throwable throwable);
}

这些是想要接收网络呼叫值的人都必须实现的方法.例如,通过将其传递给方法revealCourtPlace

These are the methods that whoever wants to receive the value of your network call will have to implement. You use this for example by passing it to the method revealCourtPlace

public void revealCourtPlace(String courtID, @Nullable RevealCourtPlaceCallbacks callbacks)
{  
   BaseService.getInstance()
      .getUniqueCourt(Session.getToken(),courtID)
      .enqueue(new Callback<JsonObject>() {
    @Override
    public void onResponse(Call<JsonObject> call, Response<JsonObject> response)
    {

        JsonObject object = response.body();
        boolean success = object.get("success").getAsBoolean(); //json objesinde dönen success alanı true ise
        if (success)
        {
            JsonArray resultArray = object.get("data").getAsJsonObject().get("result").getAsJsonArray();
            for (int i = 0; i < resultArray.size(); i++)
            {
                JsonObject jsonInfoResult = resultArray.get(i).getAsJsonObject();
                String courtName=jsonInfoResult.get("name").getAsString();

                if (callbacks != null)
                  calbacks.onSuccess(courtName);
            }

        }

    }

    @Override
    public void onFailure(Call<JsonObject> call, Throwable t)
    {
        if (callbacks != null)
            callbacks.onError(t);
    }

  });
}

要注意的重要事项:该方法返回void.您将回调作为参数传递.这些回调必须由谁调用该方法来实现,或者作为在调用位置实现的匿名类来实现.

Important things to notice: The method returns void. You pass the callbacks as an argument. These callbacks must be implemented by who's calling the method, or as an anonymous class implemented on the calling spot.

这使您可以异步接收字符串courtName,而不必担心返回值.

This enables you to receive the string courtName asynchronously and not having to worry about returning a value.

还有另一个选项可以使您的代码具有反应性.这需要更多的工作和范式的转变.它还需要Rx Java的知识.我将在此留下一个如何完成此操作的示例.请记住,有几种方法可以做到这一点.

There's another option where you could make your code reactive. This is a bit more work and a shift in paradigm. It also requires knowledge in Rx java. I'll leave here an example of how this can be done. Bear in mind that there are several ways of doing this.

首先,您应该以不同的方式定义改造接口.现在,返回类型必须是可观察的:

First you should define the retrofit interface differently. The return type must now be an observable:

public interface CourtApiClient {
    @GET(/*...*/)
    Single<JsonObject> getUniqueCourt(/*...*/);
}

我真的不知道您的呼叫的整个接口详细信息,但是这里重要的是现在的返回类型为Single.这是一个可观察到的Rx,仅发出一项或错误.该类型也应为JsonObject以外的其他类型,但这很难从代码中看出应该是什么.无论如何,这也可以.

I don't really know the entire interface details of your call, but the important part here is the return type is now Single. This is an Rx observable that emits only one item or errors. The type should also be something else than JsonObject, but this is quite hard to tell from your code what should it be. Anyway, this will work too.

下一步是简单地从revealCourtPlace方法返回结果:

The next step is to simply return the result from your revealCourtPlace method:

public Single<JsonObject> revealCourtPlace(String courtID, @Nullable RevealCourtPlaceCallbacks callbacks)
{  
   return BaseService.getInstance()
      .getUniqueCourt(Session.getToken(),courtID);
}

此处的主要区别在于,该方法现在返回可观察的对象,并且您可以随时订阅它.尽管实际上是异步的,但这使流看起来是同步的.

The key difference here is that the method now returns the observable and you can subscribe to it whenever you want. This makes the flow seem synchronous although it's in fact asynchronous.

您现在可以选择将JsonObject映射到所需的几个字符串,或者在订阅服务器中进行解析.

You have now the choice to either map the JsonObject to the several strings you want, or to do the parsing in your subscriber.

修改

自从您在注释中询问如何调用函数后,就有可能:

Since you asked in the comments how you can call your function here's a possibility:

revealCourtPlace("some court id", new RevealCourtPlaceCallbacks() {
       @Override
       public void onSuccess(@NonNull String value) {
          // here you use the string value
       }

       @Override
       public void onError(@NonNull Throwable throwable) {
          // here you access the throwable and check what to do
       }
  });

或者,您可以使调用类实现这些回调,并只需传递this:

Alternatively you can make the calling class implement these callbacks and simply pass this:

revealCourtPlace("some court id", this);

这篇关于如何从Retrofit v2的onResponse返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆