Android Worker中的Firebase事件监听器

Sas*_*nth 2 java android firebase firebase-realtime-database android-workmanager

我正在尝试从Android WorkManager实施一个带有Firebase数据库引用事件监听器的Worker。如果应用程序位于前景/背景中,则效果很好。但是,一旦我关闭了应用程序并且工作程序运行,事件监听器就不会触发,据我所知,我在日志中没有收到与此相关的任何错误消息。

这是一个示例代码:

class FirebaseWorker(context: Context, params: WorkerParameters) : Worker(context, params) {
override fun doWork(): Result {
    val firebaseDatabaseRef = FirebaseDatabase.getInstance().reference
    firebaseDatabaseRef.addListenerForSingleValueEvent(object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            // Handle DataSnapshot
        }

        override fun onCancelled(databaseError: DatabaseError) {
            // Handle DatabaseError
        }
    })

    return Result.SUCCESS
  }
}
Run Code Online (Sandbox Code Playgroud)

请让我知道在关闭应用程序后是否可以做任何事情来在后台获取和处理Firebase实时数据库数据。

Ale*_*amo 6

正如我所看到的,您正在使用addListenerForSingleValueEvent(),这意味着侦听器将精确读取一次数据。这意味着您的onDataChange()方法将使用当前值(如果可用的话从缓存中触发,否则从 Firebase 服务器中触发),并在之后立即停止侦听。在这种情况下,无需删除侦听器。唯一addListenerForSingleValueEvent需要取消的情况是,附加它时没有网络连接,并且客户端没有数据的本地副本,这可能是因为有另一个活动侦听器,也可能是因为它在磁盘上有数据副本。

如果你想继续监听变化,你应该使用addValueEventListener(). 使用这种侦听器意味着您的onDataChange()方法将立即使用当前数据调用,但是(与addListenerForSingleValueEvent)侦听器将在此之后保持活动状态,并且您onDataChange()也将被调用以进行以后的更改。

您可以addValueEventListener()在 Android 应用程序关闭后使用,但不删除它。通常,一旦使用了监听器,您还需要根据 Activity 的生命周期将其删除。如果不删除侦听器,应用程序将仅在一段时间内运行,因为如果应用程序不在前台,Android 将停止您的服务。这样做是为了在不使用应用程序时节省资源。它还可能会阻止您的应用程序进行任何网络连接,甚至完全终止应用程序进程。正如您已经提到的,除了将其设为前台服务之外,您无法采取任何措施来防止这种情况。

前台服务可能不是最适合您的情况,也不是最适合您的用户。了解有关后台服务限制的更多信息。

我的建议是使用Firebase Cloud Messaging在您的应用程序可能感兴趣的更改发生时通知您的应用程序。这样,即使您的用户将应用程序关闭,他们也会收到通知。


Dou*_*son 5

您需要阻止执行,doWork()直到所有工作完成。现在,由于addListenerForSingleValueEvent是异步的,因此您的函数将SUCCESS立即返回,这意味着WorkManager假定一切都已完成,并允许您的应用程序进程停止。

一种阻止功能的方法是使用CountDownLatch强制代码等待侦听器完成:

override fun doWork(): Result {
    val latch = CountDownLatch(1)
    val firebaseDatabaseRef = FirebaseDatabase.getInstance().reference
    firebaseDatabaseRef.addListenerForSingleValueEvent(object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            // Handle DataSnapshot
            latch.countDown()
        }

        override fun onCancelled(databaseError: DatabaseError) {
            // Handle DatabaseError
            latch.countDown()
        }
    })

    latch.await()
    return Result.SUCCESS
}
Run Code Online (Sandbox Code Playgroud)

您可能还需要考虑何时返回其他结果代码,以告诉WorkManager是否应重试已完成的工作。