Exceção de timeout do vôlei Android ao usar RequestFuture.get ()

No meu fragmento, estou tentando usar o banco de dados de filme aberto do TMDB para obter detalhes sobre os filmes "Em execução".

Se eu usar o método RequestFuture.get (time, TimeUnit) para executar essa solicitação de vôlei, sempre recebo um erro de tempo limite. Se eu testar manualmente o mesmo URL no Safari, recebo os resultados instantaneamente.

O que eu sei:

1.) Não é nenhum erro de análise JSON. (O programa nem avança para as etapas de análise)

2.) Não há problemas de internet com o AVD. (Razão explicada mais tarde).

3.) Não é um problema com minha classe de vôlei singleton ou minha fila de solicitações. (Razão explicada mais tarde).

Então, estou presumindo que estou cometendo algum outro tipo de erro em relação aos usos de vôlei / Pedido de Futuro.

Código do fragmento abaixo:

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 com o filtro para a 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

Antes de usar os métodos RequestFuture, basicamente fiz a mesma coisa implementando meu próprio Response.Listener e Response.ErrorListener no meu Fragment oncreate (em vez de StepA ();) e funcionou !!!

Abaixo está o trecho de código para isso:

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);

Portanto, minha pergunta é por que não funciona quando eu implemento os métodos de solicitação futura?

Se você me perguntar por que eu quero ir para a implementação de vôlei síncrona; é porque depois disso eu tenho que ter mais duas solicitações de vôlei que dependem dessa solicitação ser totalmente concluída com êxito. E também estou aprendendo :)

questionAnswers(2)

yourAnswerToTheQuestion