【问题标题】:finish() leaking memory but onBackPressed() is notfinish() 泄漏内存但 onBackPressed() 不是
【发布时间】:2017-07-14 16:29:54
【问题描述】:

我今天试图在一个应用程序中追踪内存泄漏,该应用程序在一些旧设备上出现内存不足。我发现的其中一个泄漏真的让我震惊。我解决了泄漏问题,但我想知道是否有人对修复工作的原因有任何见解。

正在泄漏的活动(我们称之为活动 B)有一个图标,该图标是一个“x”,用户可以退出该活动。当x被按下时,它调用finish()然后返回到活动A。这个点击事件的代码如下:

    View ivExit = findViewById(R.id.imageview_exit);
    ivExit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!isFinishing()) {
                finish();
            }
        }
    });

结果是它会按预期工作,但会泄漏内存。但是,通过一个简单的更改,我能够运行相同的精确测试而没有任何泄漏。我所要做的就是将 finish() 更改为 onBackPressed() 并且它不再泄漏。这对我来说很奇怪,因为我的印象是 onBackPressed() 和 finish() 本质上是同一件事,但其中一个泄漏内存而另一个没有。有谁知道为什么会这样?

【问题讨论】:

  • onBackPressed() 在幕后处理一些用例,但稍后它也会隐式调用finish()
  • 该设备上的操作系统版本是多少?那是 AppCompatActivity 吗?
  • 该设备是运行 Android 6.0.1 的 Nexus 5X。是的,该活动扩展了 AppCompatActivity @j2ko
  • 你问@j2ko 很有趣,因为当我在不同的设备上测试时,它没有发生。哪个更有趣,所以这种非常奇怪的差异只发生在 Nexus 上?

标签: android memory out-of-memory activity-finish onbackpressed


【解决方案1】:

区别在于FragmentedActivity(即AppCompatActivity的父级)在onBackPressed中有如下代码:

public void onBackPressed() {
    if (!mFragments.popBackStackImmediate()) {
        finish();
    }
}

而且它还没有针对finish() 的任何具体实现。 所以看起来像popBackStackImmediate 会以某种方式影响你的流程。 我找到了OS 5.1.1implementation

 @Override
 public boolean popBackStackImmediate() {
     checkStateLoss();
     executePendingTransactions();
     return popBackStackState(mActivity.mHandler, null, -1, 0);
 }

executePendingTransactions() 可能是 onBackPressed()finish() 调用之间行为不同的原因。

【讨论】:

  • 这绝对有帮助!我很好奇为什么它发生在 Nexus 而不是其他设备上。我会将此标记为正确,但我仍然很好奇。
猜你喜欢
  • 2015-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-21
  • 2014-10-25
  • 1970-01-01
相关资源
最近更新 更多