我正在尝试从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
}
}
请关闭应用程序后,我是否可以在后台获取和处理Firebase实时数据库数据。
答案 0 :(得分:3)
您需要阻止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
}
您可能还想考虑何时返回其他结果代码,以告知WorkManager是否应重试已完成的工作。
答案 1 :(得分:1)
如我所见,您正在使用addListenerForSingleValueEvent()
,这意味着侦听器将只读取一次数据。这意味着您的onDataChange()
方法被当前值(如果有的话,从缓存,否则从Firebase服务器)触发,并在此之后立即停止监听。在这种情况下,无需删除侦听器。唯一需要取消addListenerForSingleValueEvent
的情况是,如果在连接时没有网络连接,并且客户端没有数据的本地副本,则可能是因为存在另一个活动的侦听器或因为它具有副本磁盘上的数据。
如果您想继续聆听更改,则应使用addValueEventListener()
。使用这种侦听器意味着您的onDataChange()
方法将立即使用当前数据进行调用,但是(与addListenerForSingleValueEvent
不同),侦听器将在此之后保持活动状态,稍后将调用您的onDataChange()
也会改变。
您可以在关闭Android应用程序后使用addValueEventListener()
,方法是不删除它。通常,一旦使用了侦听器,您还需要根据活动的生命周期 remove it 。如果不删除监听器,则该应用程序将仅在短时间内工作,因为如果该应用程序不在前台,Android将停止您的服务。这样做是为了在不使用应用程序时节省资源。它还可能会阻止您的应用程序进行任何联网,甚至完全杀死应用程序进程。正如您已经提到的,除了使其成为前台服务之外,您无法采取任何措施来阻止这种情况。
对于您的情况,前台服务可能不是最好的选择,对于您的用户也不是最好的选择。进一步了解limitations on background services。
我的建议是使用Firebase Cloud Messaging来通知您的应用程序,它可能会引起您感兴趣的更改。因此,即使用户保持关闭状态,您的用户也会收到通知。