2013-02-13 5 views
0

У меня есть приложение BlackBerry, которое отправляет сообщения на сервер с фиксированными интервалами. Сообщения отправляются через веб-службу с использованием любого из доступных способов подключения; Wi-Fi, BIS, TCP/IP и т. Д.BlackBerry - запись и чтение из постоянного объекта vector

Поскольку сообщения отправляются непрерывно, мне нужен механизм для очереди сообщений в случае недоступности интернета и отправки сообщений в случае доступности Интернета. По этой причине я хочу сначала сохранить любое исходящее сообщение в Persistent Store, а затем прочитать Persistent Store и пропустить его, чтобы отправить все ожидающие сообщения. Любое новое сообщение должно быть сохранено на последнем месте в Постоянном хранилище.

Я называю эти два метода ниже, когда «Отправить» щелкают:

public static void saveMessage(String msg){ 
     Hashtable hashtable=new Hashtable(); 
     persistentObject = PersistentStore.getPersistentObject(KEY); 
     hashtable.put("MessageToSend", msg); 
     persistentObject.commit(); 
    } 

    public static void sendMessage(String msg){ 
     Hashtable hashtable=new Hashtable(); 
     persistentObject = PersistentStore.getPersistentObject(KEY); 
     Vector msgVector = (Vector)persistentObject.getContents(); 
     Enumeration eMsgs=msgVector.elements();; 
      /*synchronized(poObject)*/{ 
       persistentObject.setContents(msgVector); 
       persistentObject.commit(); 
      } 
      int i=0; 
      while(eMsgs.hasMoreElements()){ 
       hashtable=(Hashtable)eMsgs.nextElement(); 
       String encryptedMessage=(String)hashtable.get("MessageToSend"); 
       if(!encryptedMessage.equals("")){ 
        //check internet connection 
        String C0NNECTION_EXTENSION = checkInternetConnection(); 
        if(C0NNECTION_EXTENSION==null) 
        { 
         Dialog.alert("Check internet connection and try again"); 
         return; 
        } 
        else 
        { 
         MyScreen.PostMsgToServer(encryptedMessage); 
         hashtable.remove(encryptedMessage); 
        } 
       } 
       i++; 
      } 
    } 

Это просто попытка из учебники/примеры, которые я наткнулся. Незлая помощь.

ответ

1

Метод сохранения, который вы показываете, фактически не помещает хэш-таблицу в PersistentObject. Попробуйте что-нибудь подобное вместо этого:

public static void saveMessage(String msg){ 
    Hashtable hashtable = new Hashtable(); 
    persistentObject = PersistentStore.getPersistentObject(KEY); 
    hashtable.put("MessageToSend", msg); 
    persistentObject.setContents(hashtable); // <- you were missing this 
    persistentObject.commit(); 
} 

Это все еще, вероятно, не большой реализации, потому что я предполагаю, что вы можете назвать saveMessage() несколько раз, и добавить больше, чем одно сообщение в постоянное хранилище (?). Правильно ли это, или вы можете сохранить только одно сообщение? (Если это правда, вы можете игнорировать это следующее предложение для saveMessage())

public static void saveMessage(String msg){ 
    persistentObject = PersistentStore.getPersistentObject(KEY); 
    Hashtable hashtable = (Hashtable) persistentObject.getContents(); 
    if (hashtable == null) { 
     // lazily initialize the store contents 
     hashtable = new Hashtable(); 
     hashtable.put("MessagesToSend", new Vector()); 
    } 
    Vector queuedMessages = (Vector) hashtable.get("MessagesToSend"); 
    queuedMessages.addElement(msg); 
    // write the store contents to device storage 
    persistentObject.setContents(hashtable); 
    persistentObject.commit(); 
} 


/** 
* @param msg TODO: I'm not sure why msg needs to be passed, if 
*     saveMessage(msg) was called first? 
*/ 
public static void sendMessage(String msg){ 
    // TODO: you could choose to save the message here, so that the caller 
    // need not remember to call both sendMessage() and saveMessage() 
    // saveMessage(msg); 
    persistentObject = PersistentStore.getPersistentObject(KEY); 
    Hashtable hashtable = (Hashtable) persistentObject.getContents(); 
    if (hashtable != null) { 
     // check for saved messages first, and send them 
     Vector msgVector = (Vector) hashtable.get("MessagesToSend"); 
     Enumeration eMsgs = msgVector.elements(); 
     Vector toDelete = new Vector(); 
     while (eMsgs.hasMoreElements()) { 
       String encryptedMessage = (String)eMsgs.nextElement(); 

       // if the send was successful, you should delete message from the store 
       toDelete.addElement(encryptedMessage); 
     } 

     eMsgs = toDelete.elements(); 
     while (eMsgs.hasMoreElements()) { 
       // we can delete this sent message now 
       msgVector.removeElement((String)eMsgs.nextElement()); 
     } 
     // re-write the persistent store to the device 
     persistentObject.setContents(hashtable); 
     persistentObject.commit(); 
    } 
} 

Я также вообще хотел бы направить вас от делать все static ... что сказал, что это на самом деле больше, несвязанный вопрос здесь, и действительно, ваш постоянный объект хранилища, скорее всего, будет уникальным, глобальным объектом в вашем приложении (лучшая реализация, однако, вероятно, избежит всех этих объявлений static).

Обновление: Я немного не понимаю, как вы ожидаете назвать эти два метода. На основе вашего описания, кажется, вы звоните иsaveMessage(msg), а затем sendMessage(msg), когда Отправлено нажатием кнопки. Если вы сначала сохраните сообщение, с моей реализацией, то нет необходимости передавать msg в sendMessage(), так как sendMessage() отправит все сохранено, неотправленные сообщения в очереди (вектор). Таким образом, API для sendMessage() имеет ненужный параметр. Или я предположил, что вы можете оставить sendMessage(String) единственным общедоступным методом и получить sendMessage(String) первый звонок saveMessage(String).

В любом случае, это зависит от вас, и как вы хотите, чтобы ваш метод вызывал семантику. Основная проблема хранения и извлечения постоянных объектов должна решаться с помощью приведенного выше кода.

+0

спасибо. Идея состоит в том, чтобы сначала сохранить каждое сообщение, а затем пропустить вектор для отправки каждого сообщения. Я попробовал ваш код выше, добавив мой код отправки сообщения с ним. Ничего не произошло. По какой-то причине моя отладка работает неправильно, поэтому я не знаю точной строки, где возникает ошибка. Но я проверил сервер, и сообщения не проходят.Несмотря на то, что я нажал кнопку «Отправить» с отключенным Wi-Fi, убедитесь, что вектор уже имеет две записи, прежде чем третье сообщение будет поставлено в очередь для отправки с включенным Wi-Fi. Какая, по-видимому, причина? – Sarah

+0

@Sarah, если у вас есть какие-либо проблемы с кодом отправки, это будет отдельной проблемой. Опять же, я взял этот код из приведенного выше примера, чтобы сосредоточиться на проблеме сохранения очереди сообщений. Я бы порекомендовал сначала удалить весь код PersistentObject. Внесите 'sendMessage()' так, чтобы он просто отправил ** одно ** сообщение. Убедитесь, что он работает первым, чтобы получить сообщение на ваш сервер. Как только это будет работать, добавьте обратно в код PersistentObject. И я бы наверняка работал над тем, чтобы вернуть ваши возможности отладки, так как это поможет и всему остальному. – Nate