Java Android Worker内部的Firebase事件侦听器
我正在尝试实现一个来自Android WorkManager的Worker,它带有一个用于Firebase数据库引用的事件侦听器。如果应用程序位于前台/后台,它可以正常工作。但一旦我关闭应用程序,工作人员运行,事件侦听器就不会触发,据我所知,我在日志中没有收到任何与此相关的错误消息 下面是一个示例代码:Java Android Worker内部的Firebase事件侦听器,java,android,firebase,firebase-realtime-database,android-workmanager,Java,Android,Firebase,Firebase Realtime Database,Android Workmanager,我正在尝试实现一个来自Android WorkManager的Worker,它带有一个用于Firebase数据库引用的事件侦听器。如果应用程序位于前台/后台,它可以正常工作。但一旦我关闭应用程序,工作人员运行,事件侦听器就不会触发,据我所知,我在日志中没有收到任何与此相关的错误消息 下面是一个示例代码: class FirebaseWorker(context: Context, params: WorkerParameters) : Worker(context, params) { over
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实时数据库数据。如我所见,您正在使用
addListenerForSingleValueEvent()
,这意味着侦听器将精确读取数据一次。这意味着您的onDataChange()
方法将使用当前值触发(如果可用,则从缓存触发,否则从Firebase服务器触发),然后立即停止侦听。在这种情况下,不需要删除侦听器。唯一需要取消的addListenerForSingleValueEvent
是,如果在连接网络连接时没有网络连接,并且客户端没有数据的本地副本,这可能是因为存在另一个活动侦听器,也可能是因为它在磁盘上有数据的副本
如果要继续侦听更改,应使用addValueEventListener()
。使用这种监听器意味着您的onDataChange()
方法会立即被当前数据调用,但是(与addListenerForSingleValueEvent
不同),监听器在此之后将保持活动状态,您的onDataChange()
方法也将被调用以进行后续更改
您可以在Android应用程序关闭后使用addValueEventListener()
,方法是不删除它。通常,一旦您使用了侦听器,您还需要根据活动的生命周期。如果不删除侦听器,该应用程序将仅在一段短时间内工作,因为如果该应用程序不在前台,Android将停止您的服务。它这样做是为了在应用程序未被使用时节省资源。它还可能会阻止你的应用程序进行任何网络连接,甚至完全终止应用程序进程。正如您已经提到的,除了将其作为前台服务之外,您没有什么可以阻止它
前台服务对于您的案例来说可能不是最好的选择,对于您的用户来说也不是最好的选择。阅读更多关于
我的建议是,当您的应用程序可能感兴趣的内容发生更改时,使用此选项通知您的应用程序。因此,即使用户关闭应用程序,也会收到通知。您需要阻止执行
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
}
您还可以考虑何时返回一个不同的结果代码,以便告诉工作管理器是否完成了您的工作是否重试。
您可以添加清单声明吗?您是否为该服务使用了android:process?@AnisBENNSIR在AndroidManifest文件中没有工作者的唯一声明。Android WorkManager会根据API级别自动选择适当的方式来处理工作。它没有在文档中提到任何与AndroidManifest声明相关的内容。很抱歉我混淆了工作和工人。。。对于您的问题,我认为当应用程序位于前台/后台时,FirebaseDataBase已经初始化,但是当应用程序被终止时,您必须初始化数据库。。。文档中提到了在其他进程上调用数据库init时的有线行为。。。你能检查一下工作是否在你的主流程上执行吗?可能是这样的。我必须在下班后试用,我会检查FirebaseApp是否已初始化。我没有从文档中获得任何异常(如果没有FirebaseApp实例,它通常会引发异常)。任何FirebaseApp初始化只能在应用程序的主进程中进行。不支持在主进程以外的进程中使用Firebase,这可能会导致与资源争用相关的问题……我使用的事件侦听器并不重要。它似乎故意这样做。是的,我已经在使用fcm了,我只是在没有网络的情况下尝试一个小的解决方法,这样应用程序就可以从缓存中提取。好的,继续使用fcm。这是最好的选择。是的,我不能接受这个答案。因为它没有回答我问的问题。我想知道事件侦听器在该特定情况下无法工作的根本原因。您是否尝试使用addValueEventListener()
?在那种情况下是什么行为?我现在明白了。是的,这是它应该工作的方式,不幸的是你不能改变这种行为。我已经尝试过这种方法。但不幸的是,如果我没有为Countdownlatch或它永远运行的任务设置超时,这似乎不起作用。当应用程序位于前台/后台时,这项功能可以正常工作,但当应用程序关闭并想要获取数据时,我遇到了问题。我在项目中没有遇到任何问题,尽管我没有专门使用倒计时锁存器。我使用了其他基础设施,但结果是一样的。让我设置一个示例项目并尝试一下,这样我就可以确定当前项目中是否配置了错误的内容。在新创建的示例项目中,它可以正常工作。但我没有在我当前的项目上工作,我一定配置了一些错误的东西。我将尝试调试它,谢谢您的支持help@DougStevenson你介意共享其他基础设施吗p倒计时闩锁的更好更换方法?