概述:黑莓 - 如何訪問數據庫(或創建HTTP連接)在後臺線程時,UI應用程序不開
我們的應用延伸的UIApplication並且具有註冊的短信監聽器類在開機時。當收到符合我們標準的消息時,我們會處理消息,然後我們希望將其保存到本地SQLite數據庫,並將其上傳到Web服務器。即使UI應用程序在該階段未打開,在收到SMS後儘快發生這一點很重要。
問題:
當SMSListener實例在後臺運行,沒有UIApplication的情況下有效,並且想訪問SQLite數據庫或試圖創建一個HTTP連接「無應用程序實例」的例外是拋出。
期望的結果:
我們要處理,保存和上傳所有從SMSListener後臺線程的消息,即使UIApplication的不活躍。目前SMSListener後臺線程會將消息存儲在RuntimeStore中;當UI應用程序啓動時,它將從RuntimeStore中讀取消息並將其保存到數據庫中。但這不是一個最佳解決方案,因爲與Web服務器的同步只會在下次打開UI應用程序時纔會發生。收到消息時相當重要。
應用僞代碼:
主類,檢查啓動並創建一個SMSListener實例或從RuntimeStore得到實例。
public class OurAppUi extends UiApplication {
public static void main(String[] args) {
if (args != null && args.length > 0 && args[0].endsWith("gui")) {
// Create a new instance of the application and make the currently
// running thread the application's event dispatch thread.
OurAppUi theApp = new OurAppUi();
theApp.enterEventDispatcher();
} else {
// Entered through the alternate application entry point
SmsListener.waitForSingleton();
}
}
}
的SMSListener類監聽任何傳入的消息,利用了RuntimeStore singlton模型的。這是按預期工作的。
public class SmsListener implements javax.wireless.messaging.MessageListener {
public static SmsListener waitForSingleton() {
//Ensure this is a singleton instance.
//Open RuntimeStore and obtain the reference of BackgroundListener
RuntimeStore store = RuntimeStore.getRuntimeStore();
Object obj = store.get(ID_BACKGROUND_LISTENER);
//If obj is null, there is no current reference to BackgroundListener
//Start a new instance of BackgroundLIstener if one is not running
if(obj == null) {
store.put(ID_BACKGROUND_LISTENER, new SmsListener());
return (SmsListener)store.get(ID_BACKGROUND_LISTENER);
} else {
return(SmsListener)obj;
}
}
public void notifyIncomingMessage(MessageConnection conn) {
new Thread() {
MessageConnection connection;
Thread set (MessageConnection con) {
this.connection = con;
return (this);
}
public void run() {
try {
Message m = connection.receive();
String msg = null;
if (m instanceof TextMessage) {
TextMessage tm = (TextMessage)m;
msg = tm.getPayloadText();
}
// Process the SMS
SMSObject sms = processSMS(msg);
// Save to DataBase { Exception is Thrown Here }
SQLManager.getInstance().save(sms);
// Upload to Web Server { Exception is Thrown Here }
WebServer.upload(sms);
} catch(Exception error) {
}
}
}.set(conn).start();
}
}
當SmsListener實例要訪問SQLite數據庫或試圖創建一個HTTP連接「無應用程序實例」拋出異常。
public final class SQLManager {
private SQLManager() {
try {
db = OpenOrCreateDatabase();
} catch (MalformedURIException e) {
Debug.log(TAG, "Get connection: URI: " + e.getMessage());
} catch (ControlledAccessException e) {
Debug.log(TAG, "Get connection: Controlled Access: " + e.getMessage());
} catch (DatabasePathException e) {
Debug.log(TAG, "Get connection: Database Path: " + e.getMessage());
} catch (DatabaseIOException e) {
Debug.log(TAG, "Get connection: Database IO: " + e.getMessage());
} catch (Exception e) {
Debug.log(TAG, e);
}
}
public static synchronized SQLManager getInstance() {
if (instance == null) {
instance = new SQLManager();
}
return instance;
}
}
我們試圖店在RuntimeStore SQLite的情況下,使用相同的辛格爾頓模型作爲SMSListener但是當UI應用程序試圖訪問存儲的數據庫實例收到錯誤。
'通過備用應用程序入口點進入' - 在這裏您可能需要創建一個應用程序實例並需要調用該實例的enterEventDispatcher()。檢查這個,http://stackoverflow.com/questions/3921029/how-to-setup-alternate-entry-point-in-blackberry-application。 – Rupak