使用Room数据库的Android服务上下文

时间:2018-02-11 15:46:36

标签: android firebase firebase-cloud-messaging android-room

我正在使用同时使用 Firebase Messaging 会议室数据库的应用。

这是db的初始化方式

public static AppDatabase getInstance(final Context appContext) {
    if (INSTANCE == null) {
        INSTANCE = Room.databaseBuilder(appContext, AppDatabase.class, "dbname.db")
                // prepopulate the database after onCreate was called
                .addCallback(rdc)
                .build();
    }
    return INSTANCE;
}

MainActivity的某个地方,第一次调用AppDatabase并且数据库被实例化,一切正常并且花花公子!

现在问题在用户kill应用...

时开始

为了简单起见,想想这个应用程序就像 Whatsapp ......应用程序被杀了但是正在侦听消息的service (MyFirebaseMessagingService)仍在运行(应该如此)。< / p>

当新邮件到达且MyFirebaseMessagingService尝试通过调用AppDatabase.getInstance()将其保存到数据库时,将发生崩溃,因为创建数据库的初始context引用没有存在的时间更长,因为应用程序被杀死了。

搜索如何解决这个问题我了解到每个服务this实际上都是从context派生的,所以我立即尝试使用MyFirebaseMessagingService上下文来初始化数据库,但是,{{ 1}}你真正有权访问服务上下文,在第一条消息到达之前不会被触发

我能想到的唯一解决方案是创建一个全新的服务,MyFirebaseMessagingService::onCreate它到MainActivity,并使用新的服务上下文来创建AppDatabase实例......但它似乎完全矫枉过正。

所以我的问题是,即使应用程序被杀,如何以bindService()仍然可以使用它的方式初始化房间数据库?

3 个答案:

答案 0 :(得分:0)

getApplicationContext()在构造函数中不可用。但是它可以在onStartCommand()函数中使用。我认为这是在服务中建立/打开数据库的好地方。

答案 1 :(得分:0)

由于FirebaseMessagingService是一项服务,因此我们应该在其中拥有getApplicationContext(),因此您应该使用该服务来创建dB实例并进行必要的操作, 其他选项是创建服务或编写自定义广播接收器。

答案 2 :(得分:-1)

首先:在系统上下文(NOTIFICATION_SERVICE)中,您尝试使用Room,该Room使用应用程序上下文来访问或创建数据库。 但是那一刻应用上下文可能为空。也许是因为该应用被杀死了。 这样您就会崩溃。

第二,一些日志会很好。随着崩溃。这可能使人们无法猜测。

第三:(再次猜测)也许您应该尝试工作管理器。诸如此类:您接收数据>开始工作。将可靠地运行,而不必在那一刻正确运行。 开始here

的好地方