此活动-服务消息传递模式是否会导致内存泄漏?
我有一个 Worker Service
和一堆 Activity。每个Activity
都有一个Handler
。 Activites 可以通过使用 startService
方法将 Intents
发送到 Service
来启动作业。这些作业进入队列,并按顺序处理。
为了报告已完成作业的结果,我提供了包装在 Messenger 对象中的正确 Activity 的 Handler
以及描述作业的 Intent
。 Service
通过它向调用 Activity
发送回一些消息。这很好用。
但是,即使在相应的 Activity 被销毁之后,提供的 Handlers 似乎仍保留在内存中,并继续处理完成消息。
- 怎么会这样呢?难道处理程序不应该随着它们所属的 Activity 一起被销毁吗?
- 这会导致内存泄漏吗?
I have a Worker Service
, and a bunch of Activities. Every Activity
has a Handler
. The Activites can start jobs by sending Intents
to the Service
with the startService
method. These jobs get into a queue, and are processed sequentially.
To report back the results of the finished jobs, I supply the proper Activity's Handler
wrapped in a Messenger object with the Intent
that describes the job. The Service
sends back some message for the calling Activity
through this. This works just fine.
But the supplied Handlers
seems to remain in memory, even after the corresponding Activites
got destroyed, continuing to handle the completion messages.
- How can this be? Shouldn't the handlers be destroyed with the
Activity
they're part of? - Does this cause a memory leak?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于服务具有对 Itnents 的引用,而 Itnents 仍然具有对活动处理程序的引用,因此处理程序将无法用于垃圾收集。
您看过这段来自 Google IO 的视频吗?它是关于构建使用 RESTful Web 服务的应用程序,因此不直接相关,但委派响应长时间运行事件的责任的方法将部分映射到您的问题。
如果您不想改变太多事情,那么您需要在活动 onClose 或 onDestroy 中找到一种方法来通知服务(并通过它通知意图)不再需要它负责的长时间运行的任务。它删除了对 Handler 的引用,因此 GC 可以删除它。
或者在 ServiceHelper 类中集中管理正在运行的任务并响应其生命周期(如视频中所示)。该类可以在事情发生时发布事件,并且活动可以侦听这些事件。
这样做的好处是您的代码位于一个位置,因此当您想要更改处理服务的方式时,不必更改每个活动。
Since the Service has a reference to the Itnents which still have a reference to the Activities Handler then the Handler isn't going to become available for Garbage Collection.
Have you seen this video from Google IO? It's about building apps that use RESTful web services so isn't directly relevant but the approach of delegating the responsibility for responding to long running events will partially map to your problem.
If you don't want to change things around too much then you need a way in your Activities onClose or onDestroy to notify the Service (and through it the Intent) that the long running task it is in charge of isn't needed anymore. It removes it's reference to the Handler and so the GC can get rid of it.
That or centralise the management (as in the video) of running tasks and responding to their lifecycle in a ServiceHelper class. That class can publish events as things happen and the activities can listen for those events.
This has the benefit of your code being in one place so you don't have to change every activity when you want to change how you handle the service.