finish() 泄漏内存但 onBackPressed() 不是

finish() leaking memory but onBackPressed() is not

我今天试图在一个应用程序中追踪内存泄漏,该应用程序在一些旧设备上遇到了内存不足的情况。我发现的一个漏洞真的让我很震惊。我解决了泄漏问题,但我想知道是否有人了解此修复程序为何有效。

正在泄漏的 activity(我们称之为 activity B)有一个 'x' 图标供用户退出 activity。当按下 x 时,它调用了 finish() 然后 returns 到 activity 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() 本质上 是同一件事,但其中一个会泄漏内存而另一个不会。有谁知道为什么会这样?

区别在于FragmentedActivity (that is the parent of AppCompatActivity)在onBackPressed中有如下代码:

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

并且它没有针对finish()的任何具体实现。 所以看起来 popBackStackImmediate 会以某种方式影响您的流程。 我发现 OS 5.1.1 implementation :

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

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