Android - Firebase - 我是否需要删除每个单一的监听器?

Rya*_*yan 7 android memory-leaks firebase firebase-storage

我做了一些合理的研究,找不到我需要的答案.

我所知道的:当我将ValueEventListener附加到数据库引用时,我知道我需要稍后将其删除(现在发现一些大量的内存泄漏.

我不知道的是:我还需要分离所有其他听众吗?(这包括Firebase数据库,存储和身份验证,我正在使用的三个API)

例:

UploadTask uploadTask = ref.putFile(uploadFile);

uploadTask.addOnFailureListener(new OnFailureListener() {
    //@Override code here
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TakeSnapshot>() {
    //@Override code here
}).addOnProgressListner(new OnProgressListner<UploadTask.TakeSnapshot>() {
    //@Override code here
};
Run Code Online (Sandbox Code Playgroud)

我认为这足以向您展示我的意思.这就是我的实际代码目前的结构.

问题:

  1. 我是否需要删除所有这些侦听器,以防止在回调发生之前终止活动(系统决定,电话死机等)?
  2. 我可以以某种方式将它们捆绑起来并立即终止它们,因为我在我的代码中有30个这样的并且真的不想重构所有这些以便将所有这些侦听器分配给变量JUST所以我可以将它们传递给"removeBlahBlahBlahListener(listenerVariable)"一遍又一遍.
  3. 稍微偏离主题,但是,我懒得将我的所有代码从onCreate移动到onStart ...对于我来说,删除所有这些监听器,完成任务,调用finish()(或者其他任何杀掉的东西都是不好的做法)一个活动,虽然我想这不保证)并且只是从头开始重新创建活动?这是一个简单的小应用程序,因此重新创建活动的开销并不大.只是好奇什么是"正确的".

我想这只是计划不周和缺乏知识的结果(我只是为了好玩而不是为了工作而编程)所以如果我必须采取艰难的路线,我想这是一种学习经历,对吧?

Ben*_*lfe 5

当活动停止时自动取消注册侦听器是android及其派生类(StorageTask)中类"Task"的一个功能.

这意味着您可以执行以下操作:

UploadTask uploadTask = ref.putFile(uploadFile);

uploadTask.addOnFailureListener(thisActivity, new OnFailureListener() {
//@Override code here
}).addOnSuccessListener(thisActivity, new OnSuccessListener<UploadTask.TaskSnapshot>() {
//@Override code here
}).addOnProgressListner(thisActivity, new OnProgressListner<UploadTask.TaskSnapshot>() {
//@Override code here
};
Run Code Online (Sandbox Code Playgroud)

您还可以使用实时数据库返回的Task对象(如setValue)执行此操作,如下所示:

databaseReference.setValue("newValue").addOnSuccessListener(thisActivity, ...)
Run Code Online (Sandbox Code Playgroud)

所以直接回答你的问题:

  1. 使用活动范围版本在活动停止时自动取消注册侦听器.请注意,对于存储,您可以在活动开始时使用StorageReference.getActiveUploadTasks和StorageReference.getActiveDownloadTasks查询正在运行的操作并重新订阅.

  2. 如果使用作用域侦听器,则不需要手动取消订阅.我不知道批量取消订阅非基于任务的侦听器的方法.

  3. 好吧,我不确定你怎么能保证操作系统总能杀死你的任务而不是再次停止/启动它 - 以及你的完成代码将如何保证运行.我建议你将代码移到onStart

  • 通常"this"指的是活动内部代码中的活动.但是,如果您位于嵌套类或回调例程中,则可能不会.如果您发现自己在那里,您可以通过使用类型限定"this"来专门引用该活动 - 如"MainActivity.this"中所示 (2认同)