您的位置:首页 > 其它

Context内存泄露

2015-12-21 21:55 204 查看
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的内存泄露。

这个泄露问题在android3.0之后已被修复,因为3.0开始callback使用了弱引用保存对象。

还有一个隐藏的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内存泄露。

另外一个常见的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的内存泄露。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: