为什么我的代码在切换活动时会泄漏?

时间:2011-02-24 22:10:50

标签: android

我编写了一个地图应用程序,可以使用谷歌地图或开放街道地图 作为瓷砖供应商。 Google和OSM地图显示在单独的活动中。之后 启动画面输入选择模式活动。用户可以从该屏幕中选择 通过按钮选择Google或OSM活动。

我希望能够通过每个映射活动中的按钮在Google和OSM之间切换。当我为每个映射活动编写单击处理程序时,每个都有:

i = new Intent("com.me.otheractivity");
finish();
startActivity(i);

我在代码中的任何地方都没有服务连接或覆盖等的内部类。 当我从Select-> Google->遍历时选择(通过后退按钮) - > OSM,一切都很好 分配堆。

如果我直接从一个映射活动转到另一个映射活动,那么就是分配的堆 增长并最终在16M崩溃。显然它必须通过这条路线泄漏到某处。

我正在记录所有3个活动中的每个onCreate,Start,Resume,Pause,Stop和Destroy。 如果我使用后退按钮路线,我有日志:

选择活动 - > Google活动 - > OSM活动(在Google活动中直接通过按钮)

Select Activity Pause 
Google Activity Create
Google Activity Start 
Google Activity Resume
Select Activity Stop 
Google Activity Pause 
Open SM Activity Create 
Open SM Activity Start 
Open SM Activity Resume 
Google Activity Stop 
Google Activity Destroy

通过后退按钮,我得到了

选择活动 - > Google活动 - >选择活动 - > OSM(通过后退按钮)

Select Activity Pause 
Google Activity Create 
Google Activity Start
Google Activity Resume 
Select Activity Stop
Google Activity Pause 
Select Activity Start 
Select Activity Resume 
Google Activity Stop 
Google Activity Destroy
Select Activity Pause
Open SM Activity Create
Open SM Activity Start
Open SM Activity Resume
Select Activity Stop 

在第一个示例中,直到OSM之后,Google Activity才会停止或销毁 一个是创建,启动和恢复。泄漏是否意义重大?

我将onPauses中的所有计时器,处理程序和叠加设置为null。 (由于Google maps.jar和osmdroid.jar之间的差异,将一个活动中的两个视图组合起来并不是一个选项)

我的点击处理程序中的代码有什么问题吗?

我们将非常感谢所有建议。

编辑2月26日

继我原来的帖子之后 - 对我而言,重点是:

为什么一个活动中的onDestroy必须在第二个活动中的onResume之前运行,以便内存使用停止增长?

如果活动B中的onResume在活动A中的onDestroy之前运行,那么我看到历史堆栈上的活动数量(由adb shell dumpsys meminfo报告)每次增加一个。代码中或通过DDMS的任何数量的强制GC都不会将它们从堆栈中移除。

我已经修改了我的代码,以便clickhandler只调用finish()。在onDestroy中,我调用了startActivity()。这会在运行其他活动之前将屏幕短暂返回到选择模式活动。在这些情况下,A中的onDestroy()显然在B中的onResume()之前运行,并且历史堆栈或堆使用量都没有增长。

我只是不明白。

3 个答案:

答案 0 :(得分:0)

我强烈建议对你计划发布的所有Android应用程序使用Eclipse MAT(内存分析器)工具。

我注意到我一直致力于处理模式中的内存泄漏的应用程序,标准的java开发人员知道不会造成内存泄漏。

使用MAT工具跟踪导致泄漏的依赖项,并重新编写代码,或者在最坏的情况下,我使用反射来破坏依赖关系并允许它释放。

答案 1 :(得分:0)

你可能会遇到在你面前几分钟问到同样的内存泄漏问题here

答案 2 :(得分:0)

它与你的代码有关,正如Octavian Damiean所说,我们需要更多的信息来帮助你。我已经尝试了3个简单的活动,没有发生泄漏。每个销毁的Activity实例都可以成功进行GCed。这意味着您的应用程序中存在缺陷,或者您的应用程序显示的框架存在缺陷。在任何一种情况下,我们都需要的不仅仅是您提供的描述。

但是,正如您已经知道您正在泄露“GoogleActivity”和“OpenSMActivity”,MAT可能会有所帮助。

转储hprof文件,单击“打开查询浏览器”(左侧搜索按钮),然后“合并最短路径到GC根” - > “排除所有幻像/弱/软等参考”。填写泄漏活动的完整类名并完成。然后你会看到谁在举办你的活动。