【问题标题】:Returning list from AsyncTask从 AsyncTask 返回列表
【发布时间】:2017-06-04 10:58:09
【问题描述】:

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

【问题讨论】:

    标签: java android android-asynctask android-volley


    【解决方案1】:

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

    final ArrayList&lt;sItem&gt; list = new ArrayList&lt;&gt;();

    但是,由于异步行为,您可能仍然无法获得结果。 main, wrapping 函数立即返回列表;甚至在 Volley 启动网络请求之前。它只是在以后的某个时间由 Volley 响应填充。

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

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

    注意:因为您有嵌套调用,所以您还需要跟踪所有嵌套调用何时完成,并在每个嵌套的onResponse 中检查,以便当它是最后一次响应的调用时,它最终会启动回调。

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

    【讨论】:

    • 如果问的不是太多……正确的设计应该是什么样的?
    • @NipeshKc 实施起来很麻烦。我实际上建议您通过 RxJava/RxAndroid 查看 Observables 作为替代方案。将使整个事情更容易编写和理解。 (一旦你克服了 Observable 和 Rx 的学习曲线。)
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2018-07-14
      • 2017-12-30
      • 1970-01-01
      • 2012-11-29
      • 1970-01-01
      • 2013-03-22
      • 1970-01-01
      • 1970-01-01
      • 2012-02-13
      相关资源
      最近更新 更多