这是一种返回自定义列表的方法。但是我正在更新异步任务(OnResponse)中的列表。我不得不使用嵌套的截击请求。我已经声明了一个列表项但是无法在OnRespose方法中使用它。谁能帮我这个?如何从方法中返回列表项。
private ArrayList<sItem> fetchApiData(){
ArrayList<sItem> list= new ArrayList<>();
String url="http://www.gadgetsinnepal.com.np/wp-json/wp/v2/posts/";
JsonArrayRequest jsArrayRequest = new JsonArrayRequest
(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
try {
// Parsing json array response
// loop through each json object
for (int i = 0; i < response.length(); i++) {
sItem sitem=new sItem();
JSONObject item = (JSONObject) response
.get(i);
String id = item.getString("id");
sitem.id=id;
String date = item.getString("date");
JSONObject titleobj = item
.getJSONObject("title");
String title= titleobj.getString("rendered");
sitem.title=title;
String featuredMedia= item.getString("featured_media");
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
"http://www.gadgetsinnepal.com/wp-json/wp/v2/media/"+featuredMedia, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject nested_response) {
try {
JSONObject guilld = nested_response.getJSONObject("guid");
String featured_img_url = guilld.getString("rendered");
sitem.img=featured_img_url;
list.add(sitem);
//Toast.makeText(getApplicationContext(),"IMAGE :" + list.get(0),Toast.LENGTH_LONG).show();
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),
"ERROR "+error.getMessage(), Toast.LENGTH_LONG).show();
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
Toast.makeText(getApplicationContext(),"network timeout error",
Toast.LENGTH_LONG).show();
} else if (error instanceof AuthFailureError) {
//TODO
} else if (error instanceof ServerError) {
//TODO
} else if (error instanceof NetworkError) {
//TODO
} else if (error instanceof ParseError) {
//TODO
}
}
});
jsonObjReq.setRetryPolicy(new DefaultRetryPolicy(
7000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
MySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonObjReq);
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
MySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsArrayRequest);
return list;
}
答案 0 :(得分:0)
将您的列表声明为final或全局字段
答案 1 :(得分:0)
要在侦听器中使用闭包变量,您需要在声明变量时标记变量final。这对于列表是可以的,因为最终列表仍然可以在内部操作(您可以添加/删除项目)。
final ArrayList<sItem> list = new ArrayList<>();
但是,由于异步行为,您可能仍然无法获得结果。 main,wrap函数立即返回列表;甚至在Volley开始网络请求之前。它只会在以后的某个时候通过排球回应填补。
对fetchApiData()
的调用(现在写入)将始终返回空列表。 (但是,它是一个参考,所以取决于你如何使用它,它可能会在以后填写,但这是糟糕的设计,并且几乎总是被函数的任何消费者使用错误。)
相反,您应该为fetchApiData()
参数列表提供接口或回调函数,然后在完成从网络响应中填写列表后调用该函数。
注意:因为你有嵌套调用,所以你还需要跟踪所有嵌套调用的完成时间,并在每个嵌套onResponse
检查中,这样当它是最后一次响应调用时,它最终会被激活关闭回调。
然后,无论调用带有回调的fetchApiData(),都会知道当调用它提供的回调时,列表将被完全填充。