【问题标题】:Android AsyncTask not returning all results when retrieving information from server从服务器检索信息时,Android AsyncTask 未返回所有结果
【发布时间】:2015-08-06 00:10:25
【问题描述】:

我正在开发一个使用 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);
    }
}

【问题讨论】:

  • 在你的 HashMap 中可能有多个具有相同键“主题的值”的值,所以循环会覆盖这些值。
  • @SaNtoRiaN 为建议干杯,虽然已经检查过,但事实并非如此,每个房间都有不同的主题
  • 顺便移动部分 super.onPostExecute(map);到 onPostExecute 方法的第一行
  • 谢谢。仍然无法正常工作,但很高兴知道。

标签: android android-asynctask xmpp smack multiuserchat


【解决方案1】:

我找到了解决方案,将在此处发布以供将来使用。原来问题出在 for 循环中对 join() 的调用。有时在调用 getSubject() 之前不会建立连接,并且当这种情况发生时,主题返回为 null。如果这种情况发生多次,则将使用键“null”放入多个值,从而返回不完整的哈希映射。

我目前的解决方案是在 join() 之后调用 Thread.sleep() 以确保建立连接。如果无法建立连接,则会引发异常。可能不是最好的解决方案,但它有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-05
    • 1970-01-01
    • 2013-01-09
    • 2015-03-07
    • 2020-08-30
    相关资源
    最近更新 更多