如果按下DietFragment
中的按钮,它将在getJson()
中运行HttpRequestDietPlan
方法。之后,在Json(mealId, title)
中使用DietFragment
。
问题:DietFragment
不等待请求完成。
未来不可能,因为最低的Android版本必须为4.4
饮食片段
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class DietFragment extends Fragment {
Button button;
TextView mealOne;
public int mealId;
public DietPlan dietPlan = new DietPlan();
HttpRequestDietPlan hrt = new HttpRequestDietPlan();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_diet, null);
ET = rootView.findViewById(R.id.targetCalories_Input);
Tv1 = rootView.findViewById(R.id.targetCalories_Output);
button = rootView.findViewById(R.id.testButton);
mealOne = rootView.findViewById(R.id.meal1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
hrt.getJson();
// java.lang.IllegalMonitorStateException: object not locked by thread before wait()
mealId = hrt.dietPlan.meals.get(0).mealId;
title = hrt.dietPlan.meals.get(0).title;
mealOne.setText(title);
}
});
return rootView;
}
}
HttpRequestDietPlan
import android.os.Build;
import android.support.annotation.RequiresApi;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class HttpRequestDietPlan {
public DietPlan dietPlan = new DietPlan();
public final CompletableFuture<Response> future = new CompletableFuture<>();
public void getJson() {
OkHttpClient client = new OkHttpClient();
final Request request = new Request.Builder()
.addHeader("X-RapidAPI-Host", "spoonacular-recipe-food-nutrition-v1.p.rapidapi.com")
.addHeader("X-RapidAPI-Key", "KEY_KEY_KEY")
.url("https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/mealplans/generate?timeFrame=day&targetCalories=2000")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
call.cancel();
e.printStackTrace();
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
} else {
try {
String jsonData = response.body().string();
JSONObject json = new JSONObject(jsonData);
JSONArray arrayMeals = json.getJSONArray("meals");
for (int i = 0; i < arrayMeals.length(); i++) {
JSONObject object = arrayMeals.getJSONObject(i);
Meal meal = new Meal(
object.getInt("id"),
object.getString("title")
);
dietPlan.meals.add(meal);
System.out.println(meal);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
}
}
最佳答案
这里有一些建议:
您无需在每次调用时都创建一个新的OkHttpClient,因此我将其移到了方法之外。
然后,您可以传递回调(CallHandler),以便在调用结果可用时得到通知,并在收到结果后更新您的数据。
关于反序列化的另一件事,我建议您使用一个库(https://github.com/google/gson)反序列化对类实例的json响应。
PS:我没有测试此代码,这只是一个实现建议。
分段:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class DietFragment extends Fragment {
Button button;
TextView mealOne;
public int mealId;
public DietPlan dietPlan = new DietPlan();
HttpRequestDietPlan hrt = new HttpRequestDietPlan();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_diet, null);
ET = rootView.findViewById(R.id.targetCalories_Input);
Tv1 = rootView.findViewById(R.id.targetCalories_Output);
button = rootView.findViewById(R.id.testButton);
mealOne = rootView.findViewById(R.id.meal1);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
hrt.getJson(new HttpRequestDietPlan.CallHandler(
@Override
public void onFailure(Exception e) {
e.printStackTrace();
}
@Override
public void onSuccess(DietPlan dietPlan) {
mealId = hrt.dietPlan.meals.get(0).mealId;
title = hrt.dietPlan.meals.get(0).title;
mealOne.setText(title);
}
));
}
});
return rootView;
}
}
HttpRequestDietPlan:
import android.os.Build;
import android.support.annotation.RequiresApi;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class HttpRequestDietPlan {
private OkHttpClient client = new OkHttpClient();
public interface CallHandler {
public void onSuccess(DietPlan dietPlan);
public void onFailure(Exception e);
}
public void getJson(CallHandler callHandler) {
final Request request = new Request.Builder()
.addHeader("X-RapidAPI-Host", "spoonacular-recipe-food-nutrition-v1.p.rapidapi.com")
.addHeader("X-RapidAPI-Key", "KEY_KEY_KEY")
.url("https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/mealplans/generate?timeFrame=day&targetCalories=2000")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
call.cancel();
e.printStackTrace();
callHandler.onFailure(e)
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
IOException e = new IOException("Unexpected code " + response);
callHandler.onFailure(e)
} else {
DietPlan dietPlan = new DietPlan();
// Deserialize with a library here
try {
String jsonData = response.body().string();
JSONObject json = new JSONObject(jsonData);
JSONArray arrayMeals = json.getJSONArray("meals");
for (int i = 0; i < arrayMeals.length(); i++) {
JSONObject object = arrayMeals.getJSONObject(i);
Meal meal = new Meal(
object.getInt("id"),
object.getString("title")
);
dietPlan.meals.add(meal);
System.out.println(meal);
}
} catch (JSONException e) {
e.printStackTrace();
}
callHandler.onSuccess(dietPlan)
}
}
});
}
}