Context內存泄露

private static Drawable sBackground; 
    
@Override
protected void onCreate(Bundle state){ 
  super.onCreate(state); 
    
  TextView label =new TextView(this); 
  label.setText("Leaks are bad"); 
    
  if(sBackground ==null){ 
    sBackground = getDrawable(R.drawable.large_bitmap); 
  } 
  label.setBackgroundDrawable(sBackground); 
    
  setContentView(label); 
} 

 

如上這段代碼,context的內存泄露通常很隱蔽,但基本上是與靜態變量相關的,如上代碼中,TextView使用了靜態對象sBackground,在框架中,TextView對象會經過callback的形式回傳給sBackground,而TextView對象引用了Context實例,這就致使了當Activity調用onDestroy關閉的時候,Activity內存不會被銷燬,而是直到靜態變量sBackground被回收的時候纔會銷燬。從而引發了context的內存泄露。java

這個泄露問題在android3.0以後已被修復,由於3.0開始callback使用了弱引用保存對象。android

 

還有一個隱藏的context內存泄露以下:框架

public class MainActivity extends Activity{
	static Demo sInstance = null;
	
	@Override
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		if(sInstance == null){
			sInstance = new Demo();
		}
	}
	
	class Demo{
		void doSomething(){
		
		}
	}
}

 因爲內部類會持有外部類的實例,所以如上的靜態變量sInstance依然會引發context內存泄露。ide

 

另一個常見的context泄露在於系統Service,咱們在使用系統service的時候一般會傳遞給service當前activity的實例context,然而若是系統service自己持有靜態變量,而靜態變量又引用了context實例的話就會致使泄露。測試

  private static Context serviceContext = null;
  private static ColorManagerListener colorMgrListener;

  public static int connect(Context context, ColorManagerListener colorListener)
  {
    if ((context == null) || (colorListener == null)) {
      Log.e(TAG, "One of the parmeter passed is null");
      return -904;
    }
    colorMgrListener = colorListener;
    serviceContext = context;

 上面的代碼段是第三方公司的service提供給咱們的jar包,測試發現有context內存泄露。反編譯jar包後發現serviceContext和colorMgrListener這兩個靜態變量直接持有了context對象,會致使context的內存泄露。this

相關文章
相關標籤/搜索