我有一个客户端应用程序,它使用套接字和输入/输出流与服务器通信并请求一些数据。我创建了一个 AsyncTask 并在它的 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 是一个简单的类,可以帮助我处理从服务器获取的数据。我从服务器获取一个地图作为“用户列表”,我想在我的主活动的 ListView 中显示它,带有用户名(字符串)和在线状态(整数),然后我将它传递给本地地图对象。然后我调用我的 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 对象的条目,并为每个条目创建一个用户对象,然后将用户对象添加到我的 ArrayList“listUsers”,这是我用于 ListView 适配器的数组列表。现在,当我运行 mAdapter.notifyDataSetChanged() 时,我当然会收到一个错误,因为我正在尝试更新我的主 UI,而不是从主 UI 线程。我不能使用 onPostExecute() 方法的原因是因为我保持 doInBackground() 运行(client.run())。我这样做的原因是因为我必须保持服务器和客户端之间的连接处于活动状态,以便我可以从服务器和服务器请求数据以发送这些数据。
所以我问你们是否有办法在 AsyncTask 完成之前更新我的 ListView(在这种情况下,它永远不会到达 onPostExecute);
PS我注意到一些我无法解释的奇怪现象。当我点击我在我的活动中拥有的 EditText 并弹出键盘时,ListView 会更新并且我可以看到我的数据。