Дождаться результата запроса асинхронного залпа и вернуть его

Ниже приведен метод, в котором я пытаюсь получить пользовательский объект, вызвав getSelf(). Проблема заключается в том, что результат всегда равен нулю, так как запрос Volley не завершился во время возврата результата. Я несколько новичок в асинхронных процессах, поэтому я не уверен, что лучший способ заставить метод ждать результата вызова API, чтобы вернуть объект UserBean. Кто-нибудь может мне помочь?

public UserBean getSelf(String url){

    RpcJSONObject jsonRequest = new RpcJSONObject("getSelf", new JSONArray());

    JsonObjectRequest userRequest = new JsonObjectRequest(Request.Method.POST, url, jsonRequest, 
        new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {

                String result;
                try {
                    result = response.getString("result");
                    Gson gson = new Gson();
                    java.lang.reflect.Type listType = new TypeToken<UserBean>() {}.getType();

                    //HOW DO I RETURN THIS VALUE VIA THE PARENT METHOD??
                    userBean = (UserBean) gson.fromJson(result, listType);

                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
               Log.e("Error:", error.toString());
               finish();
            }
        }
    );

    this.queue.add(userRequest);


    return userBean;

}   

2 ответа

Для тех, кто подходит к этому вопросу от поиска и Google.

Нет причин ждать завершения асинхронного запроса, так как он асинхронный по своей структуре. Если вы хотите добиться синхронного поведения с использованием Volley, вы должны использовать так называемые фьючерсы:

String url = "http://www.google.com/humans.txt";

RequestFuture<String> future = RequestFuture.newFuture();
StringRequest request = new StringRequest(Request.Method.GET, url, future, future)
mRequestQueue.add(request);

String result = future.get(); // this line will block

Имейте в виду, что вы должны запустить блокирующий код в другом потоке, поэтому поместите его в AsyncTask (иначе future.get() заблокирует навсегда).

Вы можете достичь этого, используя библиотеку VolleyPlus https://github.com/DWorkS/VolleyPlus

У этого есть кое-что названное VolleyTickle и RequestTickle. Запрос такой же. Это синхронный запрос и только один запрос за раз.

Другие вопросы по тегам