【问题标题】:Android: onBackPressed() destroy all memory?Android:onBackPressed() 销毁所有内存?
【发布时间】:2013-02-26 09:51:44
【问题描述】:

当我在其中一个活动上按下后退按钮时,我希望返回到上一个活动,但在此之前我需要先删除内存中的所有位图和其他资源,否则会出现内存不足错误。

我试过了:

public void onBackPressed() {
   bitmap.recycle();
   System.gc();
   Runtime.getRuntime().gc();
   Intent intent = new Intent(this,GameActivity.class);
   this.startActivity(intent);
}

但仍然有内存不足的错误。

【问题讨论】:

  • Offtopic:你为什么要在 backpressed 上启动一个新的 Activity,而不是让这个 Activity 关闭。您的前一个将自动启动。
  • 不要创建意图和新活动,而是调用super.onBackPressed 代替它。猜猜你需要了解onResumeonPause的强大功能
  • 当我按下后退按钮时,它会转到我之前的活动,但活动最终的样子,而不是开始时的样子
  • 能否开发pKs
  • 只要用户按下返回按钮,之前的活动就会自动恢复。只需删除整个代码,然后在 onStop 或 onPause 上进行清理

标签: android memory android-activity back


【解决方案1】:

即使您调用 gc(),仍然存在对您的活动中无法收集的对象的引用。如果内存问题与您的活动中声明的某些对象有关,请尝试将它们的引用更改为 null,然后调用 gc()。如果您维护一些大型缓存,请尝试使用 Wea​​kReference。当然,性能会下降,但你可能不会崩溃

你得到的行为看起来更像是设计上的缺陷。该应用程序使用了太多内存,即使它可以在您当前正在测试的设备上运行,也可能在其他设备上存在问题。 System.gc() 通常应该只由操作系统调用,因为当你这样做时没有任何保证。

【讨论】:

  • 这就是我所害怕的。但是我应该怎么做才能在每次新活动开始时清理所有东西?
  • 你不能清理所有东西。原因之一是因为这不是 Java 应该如何工作的。它不提供 C/C++ 关于内存分配释放的支持。无法释放所有内容的第二个原因是系统正在引用某些对象。当调用 onDestroy() 时应该释放这些,但这不在您的控制范围内。试着理解为什么你的内存不足。 Eclipse 中的工具可以提供有关已分配内存的良好信息。
【解决方案2】:

按下后退按钮调用它:-

private void unbindDrawables(View view) {
     Log.d(TAG,"in unbindDrawables");
        if (view.getBackground() != null) {
        view.getBackground().setCallback(null);
        }
        if (view instanceof ViewGroup) {
            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            unbindDrawables(((ViewGroup) view).getChildAt(i));
            }
        ((ViewGroup) view).removeAllViews();
        view.setBackgroundResource(0);
        Log.d(TAG,"removed views");
        //finish();   

        }
 }

【讨论】:

  • 小心((ViewGroup)view).removeAllViews() - 例如,如果您有适配器视图,它可能会抛出UnsupportedOperationException
  • 当我在上一个活动(在 onStop() 中)和第二个活动(onBackPressed())中这样做时,我会回到活动的开头(我想要的)但是如果我触摸屏幕(它启动动画),我仍然有内存错误
  • 似乎即使我解开bitmpas,内存中仍然存在!我在所有活动中解除绑定时出现内存错误
【解决方案3】:

不要覆盖onBackPressed()

覆盖onStop()

@Override    
protected void onStop() {
    super.onStop();
    bitmap.recycle(); //PUT THE ACTUAL BITMAP THAT YOU WANT TO RECYCLE HERE !!!!!!!
    System.gc();
    Runtime.getRuntime().gc();
    Intent intent = new Intent(this,GameActivity.class);
    startActivity(intent);
}

【讨论】:

  • 这是一个非常糟糕的主意。如果 onStop 被系统调用,因为它需要杀死应用程序怎么办?
  • + 我不想在上一个活动停止但按下后退按钮时开始上一个活动
  • @morg 当你按下后退按钮时 onStop() 被调用,如果你想让两个活动都运行我同意这不是要走的路
  • 不,我不希望这两个活动都运行。如果我在其“onstop”上清理上一个活动的 bitmpas,当我按返回按钮回到它时,屏幕是白色的。如果我不清理 bitmpas,我之前的活动是在动画结束时而不是在开始时
【解决方案4】:

我在之前的活动中写过

@Override
public void onStop() {
    super.onStop();
 unbidDrawables and recycle bitmaps
}

@Override
public void onRestart(){
    onCreate(new Bundle());
}

这就像临时工作,但它有效!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-06
    • 1970-01-01
    • 1970-01-01
    • 2022-12-01
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多