2011-02-24 47 views
1

我已经写了一个地图应用程序,可以使用谷歌地图或开放街道地图 作为瓷砖供应商。 Google和OSM地图显示在单独的活动中。在启动屏幕后,输入选择模式活动。用户可以通过此屏幕 通过按钮选择Google或OSM活动。为什么我的代码在切换活动时泄漏?

我希望能够通过每个映射活动中的按钮在Google和OSM之间切换。当我的代码为每个映射活动的点击处理,我在每个:

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

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

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

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

选择活动 - >谷歌活动 - > OSM活动

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 

通过后退按钮去(通过在谷歌的活动按钮直接),我得到

选择活动 - >谷歌活动 - >选择活动 - > 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活动才会停止或销毁。这对泄漏有重要意义吗?

我设置为null onPauses中的所有计时器,处理程序和覆盖。 (由于Google maps.jar和osmdroid.jar之间的差异,在一个活动中结合这两个视图并不是真正的选择)

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

所有的建议将受到感谢。

EDIT 2月26日

而且我原来的职位 - 跳跃点对我来说是:

为什么要在一个活动的onDestroy到的onResume第二前运行内存使用停止增长的活动?

如果在的onResume活动乙活性A中的onDestroy之前运行,然后我看到的历史堆栈上的活动的数量(所报告的ADB壳dumpsys meminfo中)通过每次一个增加。在代码中或通过DDMS中强制GC的数量都不会将它们从堆栈中取出。

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

我只是不明白。

+0

我们需要更多代码才能提供帮助。 –

+0

我想我必须发布整件事,这会让人困惑,所以我试图将我的问题范围缩小到最低限度。我真的在寻找一个答案,为什么通过clickHandler退出,并通过后退按钮不退出? I.e有没有什么问题,完成()然后startAcivity()? – NickT

回答

0

我会大力推荐使用Eclipse MAT(内存分析器)工具来对付您计划发布的所有Android应用程序。

我已经注意到应用程序,我一直在努力结束与模式的内存泄漏标准的Java开发人员知道不会造成内存泄漏。

使用MAT工具来跟踪造成泄漏的依赖关系,并重写该代码,或者在最坏的情况下,我采取了反射来破坏依赖关系并允许它释放。

+0

我用过MAT。它只是给我“串”和类的“嫌疑人”。我真的很想让嫌疑人受到审判,或者被判无罪或者被判有罪,就像英国法律一样。 MAT给我判断“未证实”的苏格兰法律中的判决。 – NickT

+1

运行你的应用程序并查看直方图。在转储HPROF之前将垃圾收集器捣碎几次。我发现更可靠的显示仍在记忆中的东西,而不是我怀疑混淆的嫌疑人页面。任何记忆中不应该记忆的东西都是需要考虑的事情。 (你可以看看adb logcat输出,看看垃圾回收器什么时候不再释放任何东西,当你点击GC按钮时,这意味着它已经完成了它的所有工作) –

+0

顺便说一句,部分苏格兰:P –

0

您可以从相同的内存泄漏问题进行痛苦在你here

0

它涉及到你的代码前问了几分钟,因为屋大维Damiean说,我们需要更多的信息来帮助。我已经用3个简单的活动尝试过你的情况,不会发生泄漏。每个活动实例被销毁都可以成功GCed。这意味着您的应用程序可能存在缺陷,或者您的应用程序显示的框架中存在缺陷。无论如何,我们需要的不仅仅是你提供的描述。

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

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