我正在开发一个使用 Smack 库连接到 Openfire 服务器的 Android 应用程序。我有一个从 onStart() 方法调用 AsyncTask 以检索信息并将其添加到 UI 的活动。
AsyncTask 将使用 Smack MultiUserManager 类中的 getHostedRooms() 方法,遍历每个房间并从房间中获取 JID 值和主题字符串,并将该信息添加到哈希映射中。然后在 onPostExecute 方法中将该哈希映射返回给主线程。
我遇到的问题是异步任务通常不能提供所有正确的值。例如,有三个房间,通常它只会返回一两个的信息,有时会发送 null 而不是主题字符串。
当我调试代码并逐步完成它时,它每次都有效,所以我认为问题是不允许异步任务在全速运行时返回之前调用循环中的每一步。
有什么方法可以确保允许异步任务完成并按预期返回?我查看了 asynctask.get() 方法,但这似乎阻塞了 UI 线程。我已经复制了下面的 AsyncTask,如果您需要更多信息,请告诉我!
编辑:为了澄清,每次输入哈希映射的所有键值都是不同的
private class GetChatRoomData extends AsyncTask<Void, Void, HashMap<String, String>> {
private Context context;
private String username, password, returnMessage;
private XMPPTCPConnection connection;
private GetSubjectsCallBack callBack;
private GetChatRoomData(User user, GetSubjectsCallBack callBack, Context context) {
this.context = context;
this.callBack = callBack;
username = user.getUsername(); password = user.getPassword();
returnMessage = "Subjects found";
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.show();
}
@Override
protected HashMap<String, String> doInBackground(Void... params) {
XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
.setUsernameAndPassword(username, password)
.setServiceName(myservicename)
.setHost("10.0.2.2")
.setPort(5222).setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
.build();
HashMap<String, String> returnmap = new HashMap<String, String>();
try {
connection = new XMPPTCPConnection(config);
connection.setPacketReplyTimeout(10000);
connection.connect();
connection.login(username, password);
MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
List<HostedRoom> list = manager.getHostedRooms(myservicename);
if(list.size() != 0) {
for (HostedRoom room : list) {
String jid = room.getJid();
MultiUserChat tempMuc =
manager.getMultiUserChat(jid);
if (!(tempMuc.isJoined())) {
tempMuc.join(username);
}
String subject = tempMuc.getSubject();
returnmap.put(subject, jid);
}
} else {
returnMessage = "No topics created yet";
}
connection.disconnect();
} catch (Exception e) {
returnMessage = "Could not connect";
}
return returnmap;
}
@Override
protected void onPostExecute(HashMap<String, String> map) {
progressDialog.dismiss();
callBack.done(returnMessage, map);
super.onPostExecute(map);
}
}