(AudioManager)getSystemService(Context.AUDIO_SERVICE)导致内存泄漏

时间:2013-11-27 13:52:05

标签: android memory-leaks android-audiomanager

我的内存泄漏是由AudioManager引起的。所以我在我的代码中注释掉了这一行,看看它是否能解决我的问题:

public class FireRoomActivity extends Activity {

AudioManager am;
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
  }
}

它确实解决了问题,我不再有内存泄漏。那是因为Context.AUDIO_SERVICE吗?如果是,那我怎么能替换它?

如果重要的话,我在我的活动中有这个非静态类,而不是在

之外的其他地方使用
class GestureListener extends GestureDetector.SimpleOnGestureListener {
RelativeLayout parentLayout;

public void setLayout(RelativeLayout layout){
    parentLayout = layout;  }
@Override
public boolean onDown(MotionEvent e) {
    return true;
}
// event when double tap occurs
@Override
public boolean onDoubleTap(MotionEvent e) {     
    makeArrowsVisible();
    parentLayout.findViewById(R.id.cabinet_zoomed).setVisibility(View.INVISIBLE);
    Button key = (Button)parentLayout.findViewById(R.id.key);
    if(key!=null){
        key.setVisibility(View.INVISIBLE);}
    return true;
}

编辑: 堆转储的截图 enter image description here

3 个答案:

答案 0 :(得分:2)

https://gist.github.com/jankovd/891d96f476f7a9ce24e2中提到的修复对我有用。

public class ActivityUsingVideoView extends Activity {

  @Override protected void attachBaseContext(Context base) {
    super.attachBaseContext(AudioServiceActivityLeak.preventLeakOf(base));
  }
}


/**
 * Fixes a leak caused by AudioManager using an Activity context. 
 * Tracked at https://android-review.googlesource.com/#/c/140481/1 and
 * https://github.com/square/leakcanary/issues/205
 */
public class AudioServiceActivityLeak extends ContextWrapper {

  AudioServiceActivityLeak(Context base) {
    super(base);
  }

  public static ContextWrapper preventLeakOf(Context base) {
    return new AudioServiceActivityLeak(base);
  }

  @Override public Object getSystemService(String name) {
    if (Context.AUDIO_SERVICE.equals(name)) {
      return getApplicationContext().getSystemService(name);
    }
    return super.getSystemService(name);
  }
}

感谢Dejan Jankov:)

答案 1 :(得分:1)

您可以使用应用程序上下文来避免内存泄漏,以获得音频服务。

答案 2 :(得分:1)

我在另一篇文章中发现AudioManager确实保留了强大的引用,但仍然可以正确地进行垃圾回收。见this google group conversation。这就是我从中获得的东西:

这意味着如果你在进行头部转储之前通过Eclipse中的DDMS选项卡手动启动了几个垃圾收集,那么这个引用就不应该存在了。

这确实解决了"问题"对我来说,毕竟事实证明这不是一个问题...

还提到调试器不应该挂起(即使用Run As ...而不是Debug As ...)。调试器处于活动状态可能导致AudioManager保留引用,从而产生堆溢出(我没有测试过这种肯定)。