2013-02-13 78 views
0

我有一個BlackBerry應用程序,它以固定的時間間隔向服務器發送消息。消息通過使用任何可用連接方法的Web服務發送; WIFI,BIS,TCP/IP等。BlackBerry - 從持久對象向量中寫入和讀取

由於消息是不斷髮送的,我需要一種機制來排隊消息,以防萬一互聯網不可用,並在互聯網可用時發送消息。出於這個原因,我希望首先將任何傳出的消息保存在持久存儲中,然後讀取持久存儲,並通過它循環發送所有未決消息。任何新消息應保存在持久存儲的最後一個位置。

我打電話時,下面的「發送」這兩種方法是點擊:

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()會發送出全部已保存,未發送的消息在隊列中(向量)。所以,sendMessage()的API有一個不必要的參數。或者,我想你可以離開sendMessage(String)作爲唯一的公開方法,並且首先撥打sendMessage(String)saveMessage(String)

無論如何,這取決於你,以及你希望你的方法調用語義工作。上面的代碼應該解決存儲和檢索持久對象的基本問題。

+0

謝謝。這個想法是首先存儲每條消息,然後通過向量循環發送每條消息。我通過添加發送消息的代碼來嘗試上面的代碼。什麼都沒發生。出於某種原因,我的調試工作不正常,所以我不知道錯誤來自哪裏。但我檢查了服務器,並且消息沒有通過。儘管如此,我點擊了關閉Wifi的發送,以確保在第三條消息排隊等待Wifi發送開啓之前,向量已經有兩個條目。什麼似乎是原因? – Sarah 2013-02-13 11:33:45

+0

@Sarah,以及如果您的發送代碼中有任何問題,那將是一個單獨的問題。再次,我從上面的例子中拿出了這些代碼,只關注保存消息隊列的問題。我會建議先刪除所有的PersistentObject代碼。實現'sendMessage()',以便它直接發送**一條**消息。確保首先工作,將消息傳遞到服務器。一旦這個工作,然後加回PersistentObject代碼。而且,我一定會努力恢復調試能力,因爲這對其他所有方面都有幫助。 – Nate 2013-02-13 21:39:31