2015-08-06 2 views
1

Я работаю над Android-приложением, которое подключается к серверу Openfire с использованием библиотеки Smack. У меня есть активность, которая вызывает AsyncTask из метода onStart() для извлечения информации и добавления ее в пользовательский интерфейс.Android AsyncTask не возвращает все результаты при получении информации с сервера

AsyncTask будет использовать метод getHostedRooms() класса Smack MultiUserManager, пройти через каждую комнату и получить значение JID и строку темы из комнаты, добавив эту информацию в хэш-карту. Затем эта хэш-карта возвращается в основной поток в методе onPostExecute.

Проблема заключается в том, что задача async часто не дает всех правильных значений. Например, есть три комнаты, часто они будут возвращать информацию только для одного или двух, иногда отправляя нуль вместо строки темы.

Когда я отлаживаю код и проходил его шаг за шагом, он работает каждый раз, поэтому я думаю, что проблема заключается в том, что асинтеграции не разрешается вызывать каждый шаг цикла, пока он не вернется при работе на полной скорости ,

Есть ли способ, которым я могу гарантировать, что задача async разрешена для завершения и возврата, как ожидалось? Я посмотрел на метод asynctask.get(), но это, похоже, блокирует поток пользовательского интерфейса. Я скопировал AsyncTask ниже, пожалуйста, дайте мне знать, если вам нужна дополнительная информация!

Edit: Только для уточнения, все ключевые значения вводимой в хэш-карта различаются каждый раз

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); 
    } 
} 
+0

Возможно, в вашем HashMap есть более чем значение с одним и тем же ключом «значение объекта», поэтому цикл перезаписывает значения. – SaNtoRiaN

+0

@SaNtoRiaN Приветствия за предложение, уже проверили это, хотя и это не так, в каждой комнате есть другой предмет – mmillward89

+0

, кстати, переместите часть super.onPostExecute (карта); к первой строке метода onPostExecute – SaNtoRiaN

ответ

0

Я нашел решение, разместим его здесь для будущего использования. Оказывается, проблема заключалась в вызове join() в цикле for. Иногда соединение не было сделано до вызова getSubject(), и когда это произошло, объект был возвращен как null. Если это произошло несколько раз, тогда будет добавлено несколько значений с ключом «null», таким образом возвращая неполную хэш-карту.

Решение, которое я имею в настоящее время, это просто вызвать Thread.sleep() после join(), чтобы убедиться, что соединение выполнено. Если соединение не может быть сделано, генерируется исключение. Возможно, это не лучшее решение, но оно работает.

Смежные вопросы