我有这个适配器,每次创建时都会注册到ValueEventListener.如果我不拆卸它,听众会在我旋转手机时加起来,并且适配器会在片段中被破坏/重建吗?或者firebase足够聪明,知道这个特定的监听器已经存在?
PS:我试图在使用它的片段的onPause方法中取消注册此侦听器,但是firebase似乎正在删除我的缓存,因此在片段旋转之后需要一段时间来再次获取数据,这在以前没有发生过.
解决方法
>你在哪里附上你的听众?如果你将它附加到除onResume之外的任何地方,它将重新初始化你的监听器.设置侦听器时,它会触发该特定节点的所有事件.但是,我仍然在onPause和onResume中注册和取消注册我的Firebase引用
>您可以拥有任何Firebase侦听器的多个实例.
Is firebase smart enough to know that this particular listener already exists?
Firebase知道侦听器已经存在,并且不会发送两次相同的事件.但是,在旋转时,您将创建一个新的侦听器实例. Firebase无法将此视为同一实例化侦听器.因此,您再次收到所有数据.
> Firebase缓存所有数据.当附加一个片段并设置了监听器时,firebase将进行两次主要调用 –
> First – 用于检索缓存数据的查询.
> Second – 对远程数据的查询.
首先调用缓存很好,因为它仍适用于网络速度很慢甚至没有网络的情况.现在,请耐心等待……当Firebase从在线服务器接收到该快照时,它将对远程对象和本地对象进行复杂的评估. Firebase将尽最大努力使用复杂的ID合并对象,这些ID利用时间戳和黑魔法[需要来源].使用此新快照,如果需要,它会将其保存到服务器.然后,** Firebase仅在与缓存版本不同并且相对于提供所述数据的侦听器实例的更改时才向您提供日期.这种缓存驱动的结构甚至适用于您保存数据时:
>首先 – 保存到缓存.
>秒 – 触发回调.
>第三次尝试保存到服务器.
回答这个问题
如果您将监听器附加到Firebase onPause / onResume,您将再次收到所有数据.不再接收它的唯一方法是维护该侦听器的相同实例.
除了维护我的监听器实例外,我还使用了另一种解决方案.在我看来,我不喜欢它.但仍然是我经常使用的.我做的是
>我将保留最终的List< String>,名为ignoredList.此列表将由String键构成,该键将是适配器中已有对象的键.
>然后,在onPause中,我将这个数据添加到我的ignoredList中,并将childEvent监听器清零.
>在onResume回调之后,我设置了一个新的childEvent监听器实例.
>在事件监听器的onAdded上,我根据列表检查新添加的对象.如果我拥有它,我将从列表中删除它,没有别的.基本上忽略它.如果对象不在我的ignoredList中,我将像平常一样处理它.如果我从onAdded之外的一个回调中收到它(即onRemoved onChanged或onMoved),那么我将把该事件更改为列表中的该对象并从ignoredList中删除.
现在,我承认这不是最漂亮的解决方案.如果两个源正在修改相同的DataSnapshot,您可能会看到不正确的数据.这将是一个很小的机会,但完全有可能.幸运的是,如果数据集不准确,则无法保存到Firebase.