EditText导致Activity泄漏。没有当前的stackoverflow答案

时间:2016-07-30 06:00:03

标签: android memory-leaks android-edittext android-strictmode

我有一个Android Strict Mode打开的代码,VmPolicy detectAll和Penalty Death。这在应用程序中打开。

因此它有助于我检测内存泄漏。我的代码很简单,2个活动(几乎是空白的)。 MainActivity单击按钮以打开SubActivity。 SubActivity只有一个EditText。

可以在此处获取代码https://github.com/elye/issue_edittextleak

如果您运行代码,请从MainActivity转到SubActivity,然后返回MainActivity(使用Back Key),转到SubActivity,然后返回...它将崩溃

E/StrictMode: class com.elyeproj.edittextleak.SubActivity; instances=2; limit=1
android.os.StrictMode$InstanceCountViolation: class com.elyeproj.edittextleak.SubActivity; instances=2; limit=1
at android.os.StrictMode.setClassInstanceLimit(StrictMode.java:1)

这是因为它检测到SubActivity已泄露。

为什么SubActivity泄露,因为它有EditText。移除它将导致它不再泄漏。

这发生在Samsung S5 Lollipop 5.0(v21)上。它也泄漏了KitKat(第19版)。它不会发生在三星S7 Marshmallow和Nexus 6(Nougat)上。

在Emulated Nexus 5 Lollipop 5.0.2(v21)上不会发生这种情况。但是发生在模拟Nexus 5的第19版。

我检查了很多stackoverflow,但找不到解决方案。您将在https://medium.com/@elye.project/hell-level-4-unleashed-by-android-strict-mode-dare-you-challenge-it-1dc9048bb4fb#.aiffbdikn

中了解此问题的更多详细信息以及我的探索

那么我想要什么? 我认为Lollipop 5.0.2及更高版本已经解决了内存泄漏问题。但对于之前的版本,我怎么能防止泄漏,而我可以使用editText?

2 个答案:

答案 0 :(得分:3)

我认为这个问题与编辑文本无关,因为从严格模式日志SubActivity; instances=2; limit=1可以清楚地知道你有两个subActivity实例。发生这种情况是因为每次启动subActivity时都会创建它的新实例,这个问题可以通过在启动subActivity时使用启动模式标志singleInstancesingleTask来解决。它保证只有一个实例活动可以存在。

编辑1:

我玩了你的代码,发现问题在模拟Nexus 5的v19上是可重现的。我清楚这个问题与编辑文本无关,因为即使在subActivity时问题也是可以重现的没有与之相关的观点。正如在这篇Stack Oveflow帖子中所回答的那样,这可能是Strict模式中的一个错误,因为该链接指出了

  

如果某个活动已启动,并且很快退出并重新启动,那么您就是   可以获得StrictMode.InstanceCountViolation。

     

然而,这只是因为垃圾收集器还没有   最终确定了Activity的第一个实例,意思是有   临时2(或更多)内存中的实例。

     

在startActivity()或startActivityForResult()之前调用System.gc()   将停止StrictMode.InstanceCountViolation

来自android DOcs

  

不要觉得有必要修复StrictMode找到的所有内容。特别是,在正常的活动生命周期中,通常需要许多磁盘访问的情况。使用StrictMode查找您意外执行的操作。但是,UI线程上的网络请求几乎总是一个问题。

答案 1 :(得分:0)

使用此代码完成SubActivity。

在SubActivity Class文件中添加此代码。

@Override
    public void onBackPressed() {
        super.onBackPressed();
        finish();
    }