使用Android服务上下文进行Room数据库操作

12

我正在开发一个使用 Firebase MessagingRoom 数据库 的应用。

这是数据库初始化的方式

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) 仍在运行(应该是这样的)。

当一个新消息到达时,MyFirebaseMessagingService 尝试使用调用 AppDatabase.getInstance() 将其保存到数据库中,由于初始化数据库的最初 context 引用不存在了,因为应用程序已被杀死,所以会出现崩溃。

在寻找如何解决这个问题时,我发现每个服务 this 实际上都派生自 context,因此我立即尝试使用 MyFirebaseMessagingService 上下文来初始化数据库,但是,真正拥有访问服务上下文的 MyFirebaseMessagingService::onCreate 直到第一条消息到达才会触发。

我唯一能想到的解决办法是创建一个全新的服务,bindService() 它到 MainActivity,并使用该新服务的上下文来创建 AppDatabase 实例... 但这似乎完全是杀鸡焉用牛刀。

所以我的问题是,如何初始化 Room Database,以便 MyFirebaseMessagingService 可以在应用程序被杀掉的情况下仍然使用它?


2
在Service中,您可以访问getApplicationContext(),您尝试过了吗?Application实例应该在任何Service、Activity或Broadcast Receiver被创建之前创建。 - Mercato
你找到解决方案了吗? - LambergaR
基于服务的context.getApplicationContext()为空,导致程序崩溃。是否有其他建议的解决方案? - Ankit Thakur
3个回答

2

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

注:Original Answer翻译成"最初的回答"并没有上下文,无法确定具体含义,因此未进行翻译。

0
由于FirebaseMessagingService是一个服务,我们应该在那里使用getApplicationContext()来创建您的数据库实例并进行必要的操作, 其他选项是创建一个服务或编写一个自定义广播接收器。

-1

首先:从系统上下文(NOTIFICATION_SERVICE)尝试使用Room来访问或创建数据库。但是在那个时刻,应用程序上下文可能为空。可能只是因为应用程序被杀死了。所以你会得到一个漂亮的崩溃。

其次,一些日志会很好。有了崩溃,这可能会避免人们猜测。

第三:(再次猜测)也许你应该尝试使用Work Manager。类似于:你接收数据>开始工作。将可靠地运行,并且不必立即运行。一个很好的起点here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接