我真的应该删除 ValueEventListener 吗?

     2023-03-08     291

关键词:

【中文标题】我真的应该删除 ValueEventListener 吗?【英文标题】:Should I actually remove the ValueEventListener? 【发布时间】:2018-07-29 09:41:33 【问题描述】:
        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 在一个新线程中运行,我是否应该在任何时候删除它以进行正确的线程管理? (例如并行运行的线程不多)。如果是,怎么做?

【问题讨论】:

是的。您应该在组件生命周期中将其删除。否则它将在不知道组件状态的情况下为您提供回调(称为 Activity)。移除onStop()onDestroy()中的监听器。 我已经尝试删除它,我已经尝试了所有堆栈溢出的答案,但我无法删除它。有人可以帮忙吗? 【参考方案1】:

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

databaseReference.removeEventListener(valueEventListener);

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

    如果您在onStart 中添加了侦听器,则必须在onStop 中删除它。 如果您在onResume 中添加了侦听器,则必须在onPause 中删除它。 如果您在onCreate 中添加了侦听器,则必须在onDestroy 中删除它。

但请记住,onDestroy 总是被 not 调用,所以最后一个选项并不总是一个好的选择。

还有另一种不需要删除监听器的方法,那就是使用addListenerForSingleValueEvent:

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

【讨论】:

为什么不总是调用 onDestroy? 请查看here和here,以便更好地理解。 使用 addListenerForSingleValueEvent() 时,您仍应将其从 DatabaseReference 中删除。如果它永远不会触发(设备离线),则永远不会自动删除侦听器,并可能导致内存泄漏。 @javmarina 使用addListenerForSingleValueEvent() 时,没有应删除的侦听器,因为侦听器只触发一次。 我检查了addListenerForSingleValueEvent() 的源代码,它基本上添加了一个新的侦听器,当onDataChange() 被调用时它会被删除。如果两个回调方法都没有被触发,例如当设备离线时,监听器不会被移除。尽管这种情况很少见,但我们应该在代码中处理它。请参阅我对我提出的解决方案的回答。【参考方案2】:

要删除 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()

【讨论】:

【参考方案3】:

我遇到了同样的问题,导致大量内存泄漏。所以我创建了一个新类来处理添加的侦听器,并在调用相应的方法(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 侦听器,您仍然需要手动删除它们。

【讨论】:

2019 年我应该在哪里存储我的 JWT,localStorage 真的不安全吗?

】2019年我应该在哪里存储我的JWT,localStorage真的不安全吗?【英文标题】:WhereshouldIstoremyJWTin2019andisthelocalStoragereallynotsecure?【发布时间】:2019-10-1506:46:16【问题描述】:有趣的话题。由于我正在使用Node.jsApi和ReactReduxClient创建... 查看详情

孤儿删除不起作用

...,我正在阅读这个orphanRemoval参数,但对我不起作用,我真的不知道为什么。家长:@Entity@Table(schema="schema")publicclassPaisimpleme 查看详情

应该怀一颗善良本真的心去努力

那种即将重逢的喜悦便会从眼角溢出,应该怀一颗善良本真的心去努力,摇曳成一树花香,我眼中的春秋日月,没有一丝的怀念,干净、利落、洒脱,时光安静地流淌,如今,也不是第一次出远门,是苦乐交织的,有些事情,随... 查看详情

Grails 更新而不是删除

...,实际上所有的列表/显示方法都不应该显示删除标志为真的对象。我知道我可以通过在所有控制器中手动编辑我的所有CRUD方法来做到这一点,但是在使用Grails时似乎工 查看详情

Scala“未找到:object com”-如果没有其他依赖项,我真的应该在 build.sbt 中添加条目吗?

】Scala“未找到:objectcom”-如果没有其他依赖项,我真的应该在build.sbt中添加条目吗?【英文标题】:Scala"notfound:objectcom"-shouldireallyaddentryinbuild.sbtiftherearenootherdependencies?【发布时间】:2021-07-3005:43:45【问题描述】:我已... 查看详情

对于本机对等对象生命周期管理,是不是真的应该避免使用 Java 终结器?

】对于本机对等对象生命周期管理,是不是真的应该避免使用Java终结器?【英文标题】:ShouldJavafinalizerreallybeavoidedalsofornativepeerobjectslifecyclemanagement?对于本机对等对象生命周期管理,是否真的应该避免使用Java终结器?【发布时... 查看详情

关闭文件描述符并删除 inotify watch 真的有必要吗?

】关闭文件描述符并删除inotifywatch真的有必要吗?【英文标题】:Isclosingfiledescriptorandremovinginotifywatchreallynecessary?【发布时间】:2010-03-0809:22:12【问题描述】:使用pythoninotifyx,如果我需要它们直到程序退出,我是否必须删除监... 查看详情

为啥我不应该使用 Unity?

...2010-12-2209:59:03【问题描述】:我正在使用UnityIoC容器。这真的不是我做出的决定,它只是与Prism一起出现的,我一直坚持下去。我从未使用过任何其他IoC框架,我必须承认我对Unity非常满意。然而,满足感可能来自于无知,因为我... 查看详情

当我将视图添加到另一个视图(并且这两个视图都由视图控制器控制)时,我真的应该使用 addChildViewController 吗?

...一个视图(并且这两个视图都由视图控制器控制)时,我真的应该使用addChildViewController吗?【英文标题】:ShallIreallyuseaddChildViewControllerwhenIaddaviewtoanotherview(andboththeseviewsarecontrolledbyviewcontrollers)?【发布时间】:2015-04-3017:15:41【问... 查看详情

RESTful API:删除实体 - 我应该返回啥结果?

】RESTfulAPI:删除实体-我应该返回啥结果?【英文标题】:RESTfulAPI:DeleteEntity-WhatshouldIreturnasresult?RESTfulAPI:删除实体-我应该返回什么结果?【发布时间】:2018-06-1107:32:10【问题描述】:我正在实现一个RESTfulAPI,一个控制器的端... 查看详情

我应该在播放列表实体中使用啥删除规则?

】我应该在播放列表实体中使用啥删除规则?【英文标题】:WhatdeleteruleshouldIuseinaplaylistentity?我应该在播放列表实体中使用什么删除规则?【发布时间】:2016-05-0702:37:44【问题描述】:在我的数据模型中,我有一个播放列表实体... 查看详情

我应该删除使用 UIDocumentPicker 导入的文件吗?

】我应该删除使用UIDocumentPicker导入的文件吗?【英文标题】:ShouldIremovefilesimportedwithUIDocumentPicker?【发布时间】:2017-01-0917:25:35【问题描述】:所以我正在使用UIDocumentPicker在我的应用中导入文件letdocumentMenu=UIDocumentMenuViewController... 查看详情

我应该在删除之前检查一行是不是存在吗?

】我应该在删除之前检查一行是不是存在吗?【英文标题】:ShouldIcheckifarowexistsbeforedeletion?我应该在删除之前检查一行是否存在吗?【发布时间】:2010-12-1522:22:50【问题描述】:我使用Mssql作为数据库,使用EF4作为ORM/DAL。我的问... 查看详情

合并后是不是应该删除分支?

】合并后是不是应该删除分支?【英文标题】:ShouldIdeleteabranchaftermergingit?合并后是否应该删除分支?【发布时间】:2012-06-0116:19:05【问题描述】:合并分支后,是否将其从存储库中删除?但是,这是一个好习惯吗?我通常会创... 查看详情

向RNN提供句子时我应该删除停用词吗

】向RNN提供句子时我应该删除停用词吗【英文标题】:ShouldIremovestopwordswhenfeedsentencetoRNN【发布时间】:2016-09-1611:49:29【问题描述】:在词袋模型中,我知道我们应该在训练之前删除停用词和标点符号。但是在RNN模型中,如果我... 查看详情

我应该如何监听从 ObjectContext 添加/删除的实体?

】我应该如何监听从ObjectContext添加/删除的实体?【英文标题】:HowshouldIlistenforentitiesbeingadded/deletedfromanObjectContext?【发布时间】:2012-01-0815:22:31【问题描述】:据我所知,ObjectContext没有公开任何直接监听添加/删除项目的方法。... 查看详情

发布我的应用程序时我应该删除 NSLogs

】发布我的应用程序时我应该删除NSLogs【英文标题】:ShouldIremoveNSLogswhenreleasingmyApp【发布时间】:2012-01-2120:13:39【问题描述】:建议在运输应用程序中使用NSLogging吗?我知道我不应该在大量使用的循环中。或者不要太冗长地记... 查看详情

当我想删除文件时,我应该锁定它吗?

】当我想删除文件时,我应该锁定它吗?【英文标题】:ShouldIhavealockonafilewhenIwanttodeleteit?【发布时间】:2019-04-0312:15:20【问题描述】:我在本地文件系统上有一堆文件。我的服务器将提供这些文件。在某些情况下,服务器会收... 查看详情