代码之家  ›  专栏  ›  技术社区  ›  Program-Me-Rev

方法在将项添加到ArrayList之前返回

  •  -1
  • Program-Me-Rev  · 技术社区  · 6 年前

    我正在尝试填充一个 ArrayList 从一个 节点 服务器请求,但列表在添加项之前返回得太早。

    到目前为止,我是这样做的:

    List<String> entityList;
    
    public RevReadAllFromServer() {
        entityList = new ArrayList<>();
    }
    
    private synchronized void doWork() {
        StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
    
                    JSONObject json = null;
                    try {
                        json = new JSONObject(response);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
    
                    JSONArray jArr = null;
                    try {
                        jArr = json.getJSONArray("filter");
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
    
                    for (int i = 0; i < jArr.length(); i++) {
                        JSONObject e;
                        try {
                            e = jArr.getJSONObject(i);
                            Log.v("MyApp", ">>>> User Name : " + e.getString("user_name"));
                            entityList.add(e.getString("user_name"));
                        } catch (JSONException e1) {
                            e1.printStackTrace();
                        }
                    }
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.v("MyApp", "That didn't work!");
                }
            });
    
        queue.add(stringRequest);
    }
    
    public List<String> revReadAllFromServer() {
        Thread tUI = new Thread(new Runnable() {
            @Override
            public void run() {
                doWork();
            }
        });
    
        tUI.start();
        try {
            tUI.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    
        Log.v("MyApp", ">>> List Size : " + entityList.size());
    
        return entityList;
    }
    

    输出:

    2018-11-13 23:56:26.143 24807-28639/rev.ca.my_init_application V/MyApp: >>> List Size : 0
    2018-11-13 23:56:26.400 24807-24807/rev.ca.my_init_application V/MyApp: >>>> User Name :  cool_guy_101_2018  
    

    如你所见, >>> List Size : 0 之前的输出 >>>> ALL REMOTE_REV_ENTITY_GUID >>> : 1 。列表不会填充,并在添加项目之前返回。

    我怎样才能让它工作?

    提前谢谢大家。

    2 回复  |  直到 6 年前
        1
  •  0
  •   Thirumalai Parthasarathi    6 年前

    那是因为你的 queue.add 不是一种阻塞方法。它只是将您的请求排队,并在执行服务线程时对其进行服务。

    你可以用 RequestFuture 并呼叫阻塞 get 方法,用于在线程终止之前获取响应。

    顺便说一句,我不知道你打电话的时候为什么会有一条线索 join 在创建线程之后。

        2
  •  0
  •   Gratien Asimbahwe    6 年前

    您的请求是异步的,一旦响应就绪,就会填充列表。从那里你可以把它的数据用在你想要的任何事情上。

    逻辑上是这样解释的: 做-->注册任务[任务完成时:执行…]-->回来

    revReadAllFromServer() 将在启动线程后返回列表,这不会等待注册的新任务完成,而是在完成自己的任务后返回。如果你想使用注册任务的结果,那么你必须监听它的完成情况,并在实现的方法中添加指令。