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

相关文章
相关标签/搜索