您的位置:首页 > 其它

handler可能引发内存泄露问题的处理

2017-09-18 13:59 531 查看
一般我们在使用handler时,直接回书写匿名内部类或者如下方式,原则上讲是不对的。可能会造成内存泄露,发生OOM异常。

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// handler拿到消息调用分发消息和处理消息
mHandler    = new Handler() {
@Override
public void handleMessage(Message msg) {

Toast.makeText(MainActivity.this,"我是主线程的吐司",Toast.LENGTH_SHORT).show();

}
};
downloadPicture();

}


在主线程中

Toast.makeText(MainActivity.this,"我是主线程的吐司",Toast.LENGTH_SHORT).show();


引起内存泄露的原因:

当应用启动时,系统自动创建主线程Looper和LooperQueue,所以一旦消息队列中有消息,与消息绑定的主线程handler就一直处于执行过程中,那么在hanldeMessage中所引用的MainActivity就不能被回收掉掉,那么MainActivity中的资源一直被占用,由此可引发内存泄露问题。

解决第一步,把MainActivity作为context引用传递过来,修改代码如下:

自定义MyHandler把Context作为构造函数传递进来

static class MyHandler extends Handler{

private Context mContext;

public  MyHandler(Context context){
this.mContext = context;
}
}


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// handler拿到消息调用分发消息和处理消息
mHandler = new MyHandler(this){
@Override
public void handleMessage(Message msg) {

Toast.makeText(this.mContext,"我是主线程的吐司",Toast.LENGTH_SHORT).show();

}
};

downloadPicture();

}


但是仍然存在上述问题,修改两点,一是改为静态内部类,不持有外部类的引用;二是将mContext对象设为软引用对象,当内存不足时可以被回收,从而避免了内存大量被占用,造成内存泄露,甚至oom问题。

//静态内部类不持有外部类的引用
static class MyHandler extends Handler{

//将对象mContext作为软引用对象,mContext当内存不足时就会被回收。
SoftReference<Context> mContext ;
public  MyHandler(Context context){
if(context!=null) {
mContext = new SoftReference<Context>(context);
}

}
}


观看详细信息,请看链接

http://www.jb51.net/article/120627.htm
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: