我需要执行一个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;
}
答案 0 :(得分:24)
工厂方法设计模式解决方案:
要从其他方法返回或获取Volley响应,您需要编写一个Callback功能,使用Interfaces很容易
这个简单的解决方案取自我开发的Android应用程序的MVC架构,具有完整的可用性和关注点分离概念。
假设JSONObject是来自服务器的响应
步骤1)
创建 界面 ServerCallback
package xx.xx.xx.utils;
import org.json.JSONObject;
public interface ServerCallback{
void onSuccess(JSONObject result);
}
步骤2)假设您的 Volley服务器请求方法位于控制器类中,请执行此操作活动
Controller controller = new Controller();
controller.youFunctionForVolleyRequest(email, password, this, loginUrl, new ServerCallback() {
@Override
public void onSuccess(JSONObject response) {
// do stuff here
}
}
);
3)在您的Controller类中,在 inResponse()中调用 ServerCallback 函数,该函数将仅在执行完服务器响应时在Activity中执行您的代码!
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);
}
答案 1 :(得分:13)
您可能不应该在方法中返回链接。
Volley正在执行异步任务,这意味着您无法知道答案何时从您的网络服务到达,可能是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()
无论如何,如果你真的想要同步,你可以查看这篇文章:Wait for result of Async Volley request and return it
此外,请注意等待答案可能会冻结您的应用UI ,我想这不是您想要的。
希望它有所帮助。
答案 2 :(得分:1)
您无法在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/
答案 3 :(得分:0)
您可以使用未来的概念来实现
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);