BlackBerry - 当 UI 应用程序未打开时,如何在后台线程中访问数据库(或创建 HTTP 连接)

标签 blackberry

概述:

我们的应用程序扩展了 UIApplication 并具有在启动时注册的 SMS Listener 类。当收到符合我们标准的消息时,我们会处理该消息,然后将其保存到本地 SQLite 数据库并将其上传到 Web 服务器。重要的是,在收到 SMS 后尽快执行此操作,即使 UI 应用程序在该阶段尚未打开。

问题:

当 SMSListener 实例在后台运行且没有事件的 UIApplication 实例,并且想要访问 SQLite 数据库或尝试创建 HTTP 连接时,会引发“无应用程序实例”异常。

期望的结果:

即使 UIApplication 未处于事件状态,我们也希望处理、保存和上传来自 SMSListener 后台线程的所有消息。目前,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 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;
}
}

我们尝试使用与 SMSListener 相同的单例模型将 SQLite 实例存储在 RuntimeStore 中,但当 UI 应用程序尝试访问存储的数据库实例时收到错误。

最佳答案

一般来说,处理此类事件的方法是将应用程序分为两部分:

  1. 需要 UI 且仅在用户想要与应用程序交互时才需要运行的用户交互部分;
  2. 后台处理部分,用于存储数据并与远程服务器通信。

后台处理应该在 net.rim.device.api.system.Application 扩展的上下文中进行,该扩展可能应该是基于 RuntimeStore 的单例。这部分应该从您的自动运行代码开始,注册监听器并保持事件状态。确保代码在正确的上下文中执行存在一些复杂性。我有一个blog post这可能会有所帮助。

关于BlackBerry - 当 UI 应用程序未打开时,如何在后台线程中访问数据库(或创建 HTTP 连接),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12294423/

相关文章:

java - 推迟执行try-catch

java - 注释掉 System.out.println

database - BlackBerry 设备存储上的 SqLite 数据库

黑莓 MDS 模拟器 - 无法在模拟器中连接到互联网

blackberry - "Now Playing..."黑莓智能手机上的轨道信息

java - PushSDK发送推送到MDS

javascript - 为 Blackberry 开发网站的注意事项

html - 黑莓手机中的图像外观

java - 黑莓 - 将字段添加到屏幕

java - 错误 : invalid password(Not CSK password) in Building mobile app for blackberry using phonegap