【问题标题】:AddValueEventListener called multiple times on background在后台多次调用 AddValueEventListener
【发布时间】:2017-11-18 17:39:25
【问题描述】:

这是我的代码:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ValueEventListener userNavListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Log.v(Tag, "Called Multiple Times");
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    };

    mDatabase.addValueEventListener(userNavListener);
}  

我想要什么:
- 在背景上应用 addValueEventListener 的单个实例
- 因此,我确实想使用 onDestroy() 方法

如果我这样做,问题是 Log.v 打印了不止一次,而数据只更改了一次
- 我打开应用程序,
- 我再次关闭应用程序,
- 我再次打开应用程序,
- 那么问题就出现了,就是onDataChange日志打印了三次

我有什么解决方案可以防止这种情况发生吗?

感谢您抽出宝贵时间阅读此问题,如果您知道答案,请回答我的问题。

【问题讨论】:

  • 如果您不希望 Firebase 触发数据同步事件,请不要使用它来存储您的数据。这就是它的构建方式......
  • @cricket_007 问题是当数据只更改一次时,Log.v 被多次调用。
  • 那么数据实际上并没有改变一次
  • 不过,不清楚为什么这是一个实际问题。数据将始终更新为 Firebase 中的数据。显示实际代码的minimal reproducible example 以说明为什么不能多次更新数据
  • 在你的MainActivity中添加一个addValueEventListener,然后尝试打开你的应用,然后关闭它,再打开它,然后更改数据库以触发eventListener,然后看看Log说了什么,当数据库发生变化时,日志会打印 3 次

标签: android firebase firebase-realtime-database


【解决方案1】:

您必须在不再需要时删除 eventListener。

安全的地方是在onDestroy()做它

@Override
public void onDestory() {
    if (mDatabase!= null && userNavListener!= null) {
        mDatabase.removeEventListener(userNavListener);
    }
}

【讨论】:

  • 但我想让它在后台监听,我怎样才能在不调用 onDestroy() 的情况下实现它?
  • @Raika 然后不要删除它
  • 如果有特殊需要,需要创建服务在后台监听。
  • 你能教我如何用android studio创建一个只触发一次的服务吗?
  • 这里有一个问题,是什么导致了奥利奥版本中的问题。请点击此链接 - stackoverflow.com/questions/40691306/…
【解决方案2】:

如果您只想听一次,请使用addListenerForSingleValueEvent 而不是ValueEventListener

addListenerForSingleValueEvent 只读取一次数据。所以你可以这样使用它:

mDatabase.addListenerForSingleValueEvent(userNavListener)

【讨论】:

  • 我只想使用 addValueEventListener 的一个实例,但是当数据更改时,侦听器会调用多次,在这个问题中,如果您打开应用程序两次,它会打印 Log.v 三次,并打印五次如果您打开应用程序 3 次,则为 3 次。
  • 你试过我的回答了吗,它只读取一次数据,所以只有一次......这就是 addlistenerforsinglevalueevent 读取数据一次的重点,如果你使用单值事件 Log.v 只会被调用一次,因为数据只会更改一次
  • 我想你误解了我的问题,你应该尝试在你的 MainActivity 中添加一个 addValueEventListener,然后尝试打开你的应用程序,然后再次关闭它,然后再次打开它,然后更改数据库以触发 eventListener ,然后看看Log是怎么说的,当数据库发生变化时Log会打印3次
  • 是的,我知道,但我告诉过你使用 addListenerForSingleValueEvent。但是由于某种原因你不想使用它
  • 因为我想在数据库发生变化的时候监听它
猜你喜欢
  • 2020-12-02
  • 1970-01-01
  • 2018-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-02
  • 1970-01-01
相关资源
最近更新 更多