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