Android - Подождите, пока ответ залпа вернется

Мне нужно выполнить запрос Volley и дождаться ответа, чтобы разобрать его и вернуть, но понятия не имею, как этого добиться. Может кто-нибудь помочь?

Что у меня сейчас есть:

public String getLink() {
    JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {
                shortenURL = response.getString("url");
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                // TODO Auto-generated method stub

           }
    });

    queue.add(jsObjRequest);

    return shortenURL;
}

Ответы

Ответ 1

Фабричный метод проектирования шаблонов решений:

Чтобы вернуть или получить ответ Volley от другого метода, вам нужно написать функцию обратного вызова, которая очень проста с помощью интерфейсов

Это простое решение взято из моей архитектуры MVC для приложений Android, разработанной мной с концепцией повторного использования и разделения интересов.

Предположим, что JSONObject - ваш ответ от сервера

Шаг 1)

Создайте интерфейс ServerCallback

package xx.xx.xx.utils;

    import org.json.JSONObject;

    public interface ServerCallback{
        void onSuccess(JSONObject result);
    }

Шаг 2) Предположим, что ваш метод запроса сервера волейбола находится в классе контроллера, сделайте это в своей любой операции

Controller controller = new Controller();
controller.youFunctionForVolleyRequest(email, password, this, loginUrl, new ServerCallback() {
                    @Override
                    public void onSuccess(JSONObject response) {
                       // do stuff here 
                    }
                  }
               );

3) В вашем классе Controller вызовите функцию ServerCallback в inResponse() , которая будет выполнять ваш код в Activity только по ответу на выполненную миссию server-!

 public void youFunctionForVolleyRequest(final String email , final String password ,final Context context , final String URL, final ServerCallback callback)
    {
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("email", email);
        params.put("password", password);

        Log.e("sending json",params.toString());
        JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
                URL, new JSONObject(params), new Response.Listener<JSONObject>()
        {

            @Override
            public void onResponse(JSONObject response) {
               callback.onSuccess(response); // call call back function here

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                //VolleyLog.d("Volley error json object ", "Error: " + error.getMessage());

            }
        }){
            @Override
            public String getBodyContentType()
            {
                return "application/json";
            }
        };

        // Adding request to request queue
        AppController.getInstance().addToRequestQueue(jsonObjReq);

    }

Ответ 2

Вероятно, вы не должны возвращать ссылку в своем методе.

Волейлинг выполняет асинхронные задачи, это означает, что вы не можете знать, когда ответ поступит из вашего веб-сервиса, это может быть 10 секунд или 10 минут.

Если вам нужна строка в вашей функции, вы, вероятно, должны создать метод и вызвать его, когда у вас есть результат.

Вот пример:

Я думаю, это то, что у вас есть

public void getTheLinkAndCallDoSomething(){
    String link = getLink();
    doSomethingWithTheLink(link);
}

Это будет работать, если getLink() отвечает синхронно. Волейбол не в этом случае.

И это то, что вы можете сделать с Volley:

public void getTheLinkAndCallDoSomething(){
     JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.GET, 
                               url, null, new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        shortenURL = response.getString("url");
                        doSomethingWithTheLink(shortenURL);
                    }
                }, new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        // TODO Auto-generated method stub

                    }
                });

    queue.add(jsObjRequest);
}

В этом случае вы вызываете WS для получения своего URL-адреса. И как только результат будет известен, вы вызываете doSomethingWithTheLink()

Независимо от того, если вы действительно хотите быть синхронным, вы можете посмотреть сообщение: Подождите, пока не будет получен запрос Async Volley и верните его

Кроме того, имейте в виду, что ожидающий ответа может заморозить пользовательский интерфейс приложения, и я думаю, что это не то, что вы хотите.

Надеюсь, что это помогло.

Ответ 3

вы не можете вернуть anydata в свой метод getLink(). Используйте свой код как

String shortenURL  = ""; // activity global variable



public void getLink() {
        JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        shortenURL = response.getString("url");
                    }
                }, new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        // TODO Auto-generated method stub

                    }
                });

                queue.add(jsObjRequest);

}

Вы также можете увидеть дополнительную информацию по адресу http://arnab.ch/blog/2013/08/asynchronous-http-requests-in-android-using-volley/

Ответ 4

Вы можете сделать это, используя концепцию будущего

 RequestFuture<JSONObject> jsonObjectRequestFuture = RequestFuture.newFuture();
    JsonObjectRequest request = new JsonObjectRequest(ServiceUrl.BFF_BASE_URL + path, (JSONObject) postBody, jsonObjectRequestFuture, jsonObjectRequestFuture);
requestQueue.add(request);
JSONObject jsonObject = jsonObjectRequestFuture.get(30, TimeUnit.SECONDS);