我想从我的函数返回一个字符串值。但我不知道如何处理它?我尝试了最终的单阵列解决方案,但没有成功。
这是我的代码:
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 ?
}
答案 0 :(得分:16)
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);
答案 1 :(得分:0)
使用retrofit2可以进行同步调用:
Callback<JsonObject> callback = BaseService.getInstance().getUniqueCourt(Session.getToken(),courtID)
Response<JsonObject> response = callback.execute();
...
但是,同步请求会在Android 4.0或更高版本上触发应用程序崩溃。您会遇到NetworkOnMainThreadException
错误。
更多信息here。