我应该删除ValueEventListener吗?

时间:2018-02-19 07:31:45

标签: java android multithreading firebase firebase-realtime-database

        DatabaseReference Ref = FirebaseDatabase.getInstance().getReference(Constants.Client + "/" + path);
        Ref.keepSynced(true);
        Ref.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

我理解ValueEventListener在一个新线程中运行,我是否应该在任何时候实际删除它以进行正确的线程管理? (没有太多并行运行的线程的示例)。如果是的话,该怎么做?

3 个答案:

答案 0 :(得分:5)

在谈论听众时,是的,您需要根据活动的生命周期删除它们,为此您需要使用以下代码行:

databaseReference.removeEventListener(valueEventListener);

请记住,如果你不这样做,你最终会浪费你的电池和带宽。所以:

  1. 如果您已在onStart中添加了监听器,则必须在onStop中将其删除。
  2. 如果您已在onResume中添加了监听器,则必须在onPause中将其删除。
  3. 如果您已在onCreate中添加了监听器,则必须在onDestroy中将其删除。
  4. 但请记住,onDestroy总是被 not 调用,所以最后一个选项并不总是一个不错的选择。

    还有另一种方法,无需删除侦听器,即使用addListenerForSingleValueEvent时:

      

    为此位置的数据中的单个更改添加侦听器。

答案 1 :(得分:4)

要删除ValueEventListener,您可以执行以下操作:

删除侦听器的匿名性。

更改此代码: -

      Ref.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

进入这个:

   ValueEventListener listener= new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
Ref.addValueEventListener(listener);

现在您将能够删除侦听器:

   @Override
public void onDestroy() {
if (Ref != null && listener != null) {
   Ref.removeEventListener(listener);
    }
 }

您需要删除它,因此侦听器不会继续在其他活动生命周期中运行,例如onDestroy()

答案 2 :(得分:1)

我遇到了同样的问题,并且导致很多内存泄漏。因此,我创建了一个新类来处理添加的侦听器,并在调用相应的方法(onPause(),onStop()或onDestroy())时将其删除。使用androidx.lifecycle库,适用于活动和片段(实际上,任何实现LifecycleOwner的类)。

您可以检查代码here。如果不手动添加androidx.lifecycle依赖项,您可能会很好,但是也可以将其添加到模块级build.gradle:

implementation 'androidx.lifecycle:lifecycle-runtime:VERSION'

在您当前的代码中,而不是:

databaseReference.addValueEventListener(valueEventListener);
// or
databaseReference.addListenerForSingleValueEvent(valueEventListener);

您需要使用:

addValueEventListener(databaseReference, valueEventListener); 
// or
addListenerForSingleValueEvent(databaseReference, valueEventListener);

当从使用FirebaseListenerHandler的活动或片段中调用时有效,如gist所示。如果您需要在其他情况下(例如服务)添加Firebase侦听器,则仍然必须手动将其删除。