繁体   English   中英

如何从Retrofit v2的onResponse返回值

[英]How can I return value from onResponse of Retrofit v2

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

这是我的代码:

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这样。 但是,您可以传递值或重构代码以使用Rx之类的东西。

让我解释。 因此,一个选项是通过回调传递您想要的字符串值。 假设您有界面:

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

     void onError(@NonNull Throwable throwable);
}

这些方法是任何想要接收网络呼叫价值的人必须实施的方法。 例如,您可以将其传递给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。 您将回调作为参数传递。 这些回调必须由调用该方法的人或作为在调用点上实现的匿名类来实现。

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

还有另一个选项可以让您的代码被动反应。 这是一项更多的工作和范式的转变。 它还需要Rx java中的知识。 我将在这里留下一个如何做到这一点的例子。 请记住,有几种方法可以做到这一点。

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

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

我真的不知道你的调用的整个接口细节,但这里的重要部分是返回类型现在是Single 这是一个Rx observable,只发出一个项目或错误。 该类型也应该是JsonObject以外的其他类型,但是很难从代码中分辨出它应该是什么。 无论如何,这也会奏效。

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

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

这里的关键区别是该方法现在返回observable,您可以随时订阅它。 这使得流看起来是同步的,尽管它实际上是异步的。

您现在可以选择将JsonObject映射到您想要的几个字符串,或者在您的订阅者中进行解析。

编辑

由于您在评论中询问如何调用您的函数,这是一种可能性:

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

revealCourtPlace("some court id", this);

使用retrofit2可以进行同步调用:

Callback<JsonObject> callback = BaseService.getInstance().getUniqueCourt(Session.getToken(),courtID)
Response<JsonObject> response = callback.execute();
...

但是,同步请求会在Android 4.0或更高版本上触发应用程序崩溃。 您将遇到NetworkOnMainThreadException错误。

更多信息在这里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM