Android volley Timeout Ausnahme bei Verwendung von RequestFuture.get ()
In meinem Fragment versuche ich, TMDBs offene Filmdatenbank zu verwenden, um Details zu "Now Playing" -Filmen abzurufen.
Wenn ich die RequestFuture.get (time, TimeUnit) -Methode verwende, um diese Volley-Anfrage auszuführen, erhalte ich immer einen Timeout-Fehler. Wenn ich dieselbe URL in Safari manuell teste, erhalte ich die Ergebnisse sofort.
Was ich weiß
1.) Es handelt sich nicht um einen JSON-Parsing-Fehler (das Programm fährt nicht einmal mit den Parsing-Schritten fort).
2.) Keine Internetprobleme mit AVD. (Grund später erklärt).
3.) Kein Problem mit meiner Volley-Singleton-Klasse oder meiner Anforderungswarteschlange. (Grund später erklärt).
So gehe ich davon aus, dass ich in Bezug auf die Verwendung von Volleyball / Request Future einen anderen Fehler mache.
Fragment Code unten:
public class BoxOffice extends android.support.v4.app.Fragment {
private VolleySingleton volleySingleton;
private RequestQueue requestQueue;
private ImageLoader imageLoader;
private ArrayList<MyMovie> movieList;
private MyUriBuilder mBuilder;
public BoxOffice() {
// Required empty public constructor
volleySingleton = VolleySingleton.getInstance();
requestQueue = volleySingleton.getRequestQueue();
mBuilder = new MyUriBuilder();
movieList = new ArrayList<>();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
StepA();
}
public void StepA() {
String url = mBuilder.getURL("box");
Log.d("RT", "StepA initiated - "+ url); // Url is perfect - works when copied in Safari.
RequestFuture<JSONObject> futureA = RequestFuture.newFuture();
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, (String) null, futureA, futureA);
requestQueue.add(request);
try {
JSONObject response = futureA.get(30, TimeUnit.SECONDS);
Log.d("RT", "StepA - response received"); //Never reaches this step
parseJsonFeed(response);
} catch (InterruptedException e) {
Log.e("RT", "StepA - InterruptedException - " + e);
e.printStackTrace();
} catch (ExecutionException e) {
Log.e("RT", "StepA - ExecutionException - " + e);
e.printStackTrace();
} catch (TimeoutException e) {
Log.e("RT", "StepA - TimeoutException - " + e);
e.printStackTrace();
}
Log.d("RT", "StepA END");
}
public void parseJsonFeed(JSONObject response) {
Log.d("RT", "StepA - parseFeed Begin");
if (response == null || response.length() == 0) {
return;
}
MyMovie currentMovie = null;
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
if (response.has("results")) {
Log.d("RT", "StepA - results");
JSONArray resultList = response.getJSONArray("results");
for (int i = 0; i < 3; i++) {
Log.d("RT", "movie " + i);
JSONObject movieElement = resultList.getJSONObject(i);
if (movieElement.has("id") && movieElement.has("title")) {
currentMovie = new MyMovie();
currentMovie.setTmdb_id(movieElement.getString("id"));
currentMovie.setTitle(movieElement.getString("title"));
if (movieElement.has("release_date")) {
currentMovie.setReleaseDate(dateFormat.parse(movieElement.getString("release_date")));
} else {
currentMovie.setReleaseDate(dateFormat.parse("0000-00-00"));
}
movieList.add(i, currentMovie);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
Log.d("RT", "StepA - parseFeed END");
}
}
Logcat mit dem Filter für das Tag "RT":
05-30 15:17:51.710 D/RT﹕ TL - Constructor Called
05-30 15:17:51.800 D/RT﹕ StepA initiated - https://api.themoviedb.org/3/movie/now_playing?api_key=##### (link works fine)
05-30 15:18:21.820 E/RT﹕ StepA - TimeoutException - java.util.concurrent.TimeoutException
05-30 15:18:21.820 D/RT﹕ StepA END
Vor der Verwendung der RequestFuture-Methoden habe ich im Grunde das Gleiche getan, um meinen eigenen Response.Listener und Response.ErrorListener in meinem Fragment oncreate (anstelle des StepA ();) zu implementieren, und es hat funktioniert !!!
Below ist das Code-Snippet dafür:
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, mBuilder.getURL("box"), (String) null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
parseJsonFeed(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), error.toString(), Toast.LENGTH_LONG).show();
}
});
requestQueue.add(request);
So ist meine Frage, warum es nicht funktioniert, wenn ich die zukünftigen Methoden der Anfrage implementiere?
Wenn Sie mich fragen, warum ich für die synchrone Volley-Implementierung gehen möchte; es liegt daran, dass ich danach zwei weitere Volley-Anfragen haben muss, die davon abhängen, dass diese Anfrage vollständig und erfolgreich abgeschlossen wurde. Und ich lerne auch:)