Java 如何使用okhttp获取异步调用以返回对主线程的响应?
我正在尝试为Android制作一个程序,我正在使用okhttp进行json调用。 我真的想将我的响应返回到我正在创建的线程的外部。我需要为异步调用创建线程,否则我将得到NetworkOnMainThreadException。问题是,我似乎无法在“onResponse”方法之外获取响应字符串,即使我的responseString是类中的全局变量。因为它是异步的,所以线程在返回之前不会及时运行以获取全局变量中的值。在返回responseString值之前,如何确保获得响应 这是我的密码:Java 如何使用okhttp获取异步调用以返回对主线程的响应?,java,android,json,asynchronous,okhttp,Java,Android,Json,Asynchronous,Okhttp,我正在尝试为Android制作一个程序,我正在使用okhttp进行json调用。 我真的想将我的响应返回到我正在创建的线程的外部。我需要为异步调用创建线程,否则我将得到NetworkOnMainThreadException。问题是,我似乎无法在“onResponse”方法之外获取响应字符串,即使我的responseString是类中的全局变量。因为它是异步的,所以线程在返回之前不会及时运行以获取全局变量中的值。在返回responseString值之前,如何确保获得响应 这是我的密码: publ
public static String getUserProductCategoriesFromServer(Activity activity, final String UID, final String EXPIRY, final String CLIENT, final String ACCESSTOKEN)
{
activity.runOnUiThread(new Runnable()
{
@Override
public void run()
{
final OkHttpClient client = new OkHttpClient();
final Request request = new Request.Builder()
.url(JsonStorage.getJsonUserProductCategories())
.get()
.addHeader("access-token", ACCESSTOKEN)
.addHeader("client", CLIENT)
.addHeader("expiry", EXPIRY)
.addHeader("uid", UID)
.build();
client.newCall(request).enqueue(new Callback()
{
@Override
public void onFailure(Call call, IOException e)
{
}
@Override
public void onResponse(Call call, Response response) throws IOException
{
try
{
response = client.newCall(request).execute();
String json = response.body().string();
JSONObject jsonObject = new JSONObject(json);
JSONArray jsonData = (JSONArray) jsonObject.getJSONArray("user_product_category_names");
responseString = jsonData.toString();
Log.v("TEST1", jsonData.toString()); //RETURNS JSON :D
Log.v("TEST2", responseString); //RETURNS JSON :D
} catch (IOException | JSONException e) {
e.printStackTrace();
}
}
});
}
});
Log.v("TEST3", responseString); //RETURNS "NULL" :(
return responseString;
}
从异步世界到同步世界(基于线程)获得结果的常用方法是使用。许多库实现了这样的接口,例如Guava。标准java的实现名为。它使用具有不同名称和签名的方法,但适配器很容易实现:
class CallbackFuture extends CompletableFuture<Response> implements Callback {
public void onResponse(Call call, Response response) {
super.complete(response);
}
public void onFailure(Call call, IOException e){
super.completeExceptionally(e);
}
}
有了
响应
,您可以像在第一个变体中一样提取响应字符串。将结果从异步世界提取到同步(基于线程)的常用方法是使用。许多库实现了这样的接口,例如Guava。标准java的实现名为。它使用具有不同名称和签名的方法,但适配器很容易实现:
class CallbackFuture extends CompletableFuture<Response> implements Callback {
public void onResponse(Call call, Response response) {
super.complete(response);
}
public void onFailure(Call call, IOException e){
super.completeExceptionally(e);
}
}
有了响应
,您可以像在第一个变体中一样提取响应字符串
。您可以返回调用并将结果排入ui组件的队列,此外,您还可以创建助手函数来序列化json数据,也可以使用GSONY。您可以为响应后要执行的下一个任务创建更多函数,并在onResponse方法中调用这些方法。您可以返回调用并将结果排入ui组件的队列,此外,您还可以创建助手函数来序列化json数据,也可以使用GSONY您可以为响应后要执行的下一个任务创建更多函数,并在onResponse方法中调用这些方法谢谢!为了详细说明是否有其他人遇到了这个问题:因为我支持API 23,并且CompletableFuture可以从API 24+获得,所以我使用了streamsupport cfuture库,它是此功能的一个后端口(我认为它支持一直到API 16)。因为我正在使用这个定制回调,所以我可以在主线程上运行它,并且不再像okhttp3在使用它们的实现时给我的那样得到NetworkOnMainThreadException。谢谢你!非常感谢。为了详细说明是否有其他人遇到了这个问题:因为我支持API 23,并且CompletableFuture可以从API 24+获得,所以我使用了streamsupport cfuture库,它是此功能的一个后端口(我认为它支持一直到API 16)。因为我正在使用这个定制回调,所以我可以在主线程上运行它,并且不再像okhttp3在使用它们的实现时给我的那样得到NetworkOnMainThreadException。谢谢你!