从AsyncTask返回列表

时间:2017-01-19 16:32:35

标签: java android android-asynctask android-volley

这是一种返回自定义列表的方法。但是我正在更新异步任务(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;
}

2 个答案:

答案 0 :(得分:0)

将您的列表声明为final或全局字段

答案 1 :(得分:0)

要在侦听器中使用闭包变量,您需要在声明变量时标记变量final。这对于列表是可以的,因为最终列表仍然可以在内部操作(您可以添加/删除项目)。

final ArrayList<sItem> list = new ArrayList<>();

但是,由于异步行为,您可能仍然无法获得结果。 main,wrap函数立即返回列表;甚至在Volley开始网络请求之前。它只会在以后的某个时候通过排球回应填补。

fetchApiData()的调用(现在写入)将始终返回空列表。 (但是,它是一个参考,所以取决于你如何使用它,它可能会在以后填写,但这是糟糕的设计,并且几乎总是被函数的任何消费者使用错误。)

相反,您应该为fetchApiData()参数列表提供接口或回调函数,然后在完成从网络响应中填写列表后调用该函数。

注意:因为你有嵌套调用,所以你还需要跟踪所有嵌套调用的完成时间,并在每个嵌套onResponse检查中,这样当它是最后一次响应调用时,它最终会被激活关闭回调。

然后,无论调用带有回调的fetchApiData(),都会知道当调用它提供的回调时,列表将被完全填充。