2013-11-27 21 views
3

我的內存泄漏是由AudioManager引起的。所以我註釋掉這一行我的代碼,看看是否能解決我的問題:(AudioManager)getSystemService(Context.AUDIO_SERVICE)導致內存泄漏

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

+0

後的實際證據,導致你相信你有內存泄漏。 –

+0

謝謝。編輯。 – Nazerke

回答

0

可以使用避免內存泄漏應用程序上下文獲取音頻服務。

+0

儘管這也是我的第一次猜測,但我很驚訝地發現它不起作用(至少不是在我的特殊情況下)。經過一番調查,我最終得出了我在下面的答案中發佈的結論...... –

1

我發現在另一篇文章中,AudioManager確實保留了強烈的參考,但仍然會正確地進行垃圾收集。請參閱this google group conversation。下面是我從中得到的結果:

這意味着如果在採用頭轉儲之前通過Eclipse中的DDMS選項卡手動啓動一些垃圾收集,則此引用不應再存在。

這確實解決了我的「問題」,因爲它變成了不是一個問題,畢竟......

也有人mentionned調試器不應該是掛機(即使用運行方式。 ..而不是調試爲...)。調試器處於活動狀態可能會導致引用由AudioManager保存,從而造成堆溢出(我沒有測試過這種肯定)。

1

修正提到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); 
    } 
} 

由於德揚Jankov :)