如何在AsyncTask完成之前更新它

时间:2013-10-13 21:51:42

标签: java android android-listview android-asynctask

我有一个客户端应用程序,它使用套接字和输入/输出流与服务器通信并要求一些数据。我创建了一个AsyncTask,并在doInBackground()上创建了连接并发送/接收数据。
doInBackground():

@Override
        protected Object doInBackground(Object... objIn) {

            // we create a TCPClient object and
            client = new T_Client(new T_Client.OnMessageReceived() {
                @Override
                // here the messageReceived method is implemented
                public void messageReceived(Object objIn) {
                    Log.v(tagTask, "Object Received: " + objIn);                        
                        Log.w(tagTask, "Object returned: " + objIn);
                        mapReturn = (Map<String, Integer>) objIn;
                        Log.i(tagTask, "Map Object Returned: " + mapReturn);
                        onProgressUpdate();                     
                }
            });
            client.run();

            return objIn;
        }

User是一个简单的类,可以帮助我处理从服务器获取的数据。 我从服务器获得一个Map作为“用户列表”,我想在我的主要活动的ListView中显示,用户名(字符串)和OnLine状态(整数),我将它传递给本地Map对象。然后我调用AsyncTask的onProgressUpdate()方法 的 onProgressUpdate():

@Override
        protected void onProgressUpdate(Void... voids) {
            super.onProgressUpdate();

            for (Entry<String, Integer> entry : mapReturn.entrySet()) {
                if (entry.getValue() == 1) {
                    User user = new User(entry.getKey(), "YES");
                    Log.v(tagTask, "UserName: " + user.getUser());
                    Log.v(tagTask, "Online Status : " + user.getOnLine());
                    listUsers.add(user);
                } else if (entry.getValue() == 0) {
                    User user = new User(entry.getKey(), "NO");
                    Log.v(tagTask, "UserName: " + user.getUser());
                    Log.v(tagTask, "Online Status : " + user.getOnLine());
                    listUsers.add(user);
                }
            }

             mAdapter.notifyDataSetChanged();
        }

    }

在这里,我遍历Map对象的条目,并为每个条目创建一个User对象,然后将用户对象添加到我的ArrayList“listUsers”,这是我用于ListView适配器的数组列表。现在当我运行mAdapter.notifyDataSetChanged()时,我得到一个错误,因为我正在尝试更新我的主UI,而不是从主UI线程。 我不能使用onPostExecute()方法的原因是因为我保持doInBackground()运行(client.run())。我这样做的原因是因为我必须保持服务器和客户端之间的连接,以便我可以从服务器和服务器请求数据来发送这些数据。

所以我问你们,在AsyncTask完成之前是否有办法更新我的ListView(在这种情况下,它永远不会进入onPostExecute);

P.S。我注意到一些我无法解释的奇怪事。当我点击我的活动中的EditText并弹出键盘时,ListView会更新,我可以看到我的数据。

1 个答案:

答案 0 :(得分:0)

  

我无法使用onPostExecute()方法的原因是因为我保持doInBackground()运行(client.run())。

恕我直言,这是对AsyncTask的不当使用。当您不是创建和管理池的人时,不要无限期地从资源池中占用资源。

相反,创建自己的线程。然后使用Handler将消息传递给在主应用程序线程上运行的代码,以更新列表。