概述:
我们的应用程序扩展了UIApplication并具有一个在启动时注册的SMS Listener类。当收到符合我们标准的消息时,我们处理消息,然后我们要将其保存到本地SQLite数据库并将其上载到Web服务器。收到SMS后,即使UI应用程序未在该阶段打开,这一点很快就会发生。
问题:
当SMSListener实例在后台运行时,如果没有UIApplication实例处于活动状态,并且想要访问SQLite数据库或尝试创建HTTP连接,则会抛出“No Application Instance”异常。
期望的结果:
我们希望处理,保存和上传SMSListener后台线程中的所有消息,即使UIApplication未处于活动状态。目前,SMSListener后台线程将消息存储在RuntimeStore中;启动UI应用程序时,它会从RuntimeStore读取消息并将其保存到数据库中。但这不是最佳解决方案,因为与Web服务器的同步也只会在下次打开UI应用程序时发生。重要的是它在收到消息时会同步。
应用程序伪代码:
Main Class,检查启动并创建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 Singleton模型。这是按预期工作的。
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;
}
}
我们尝试将SQLite实例存储在RuntimeStore中,使用与SMSListener相同的Singleton模型,但在UI应用程序尝试访问存储的数据库实例时收到错误。
答案 0 :(得分:2)
一般来说,处理此类活动的方法是将应用程序分为两部分:
后台处理应该在net.rim.device.api.system.Application的扩展上下文中进行,该扩展可能应该是基于RuntimeStore的单例。此部分应从您的自动运行代码启动,注册侦听器并保持活动状态。确保代码在正确的上下文中执行时涉及一些复杂性。我有blog post可能会有帮助。