在LoaderCallbacks中使用CursorAdapter造成的内存泄露问题

今天在项目中被一个OutOfMemoryError问题困扰了很久,找了半天才发现是由于 在实现LoaderCallbacks的回调方法onLoadFinished(Loader<D> loader, D data)中使用CursorAdpater造成了内存泄露,在onLoadFinished(Loader<D> loader, D data)中的data传的是一个cursor回来,然后使用listView.setAdapter(new CursorAdapter(cursor)),这样一来在 横竖屏的时候每翻转一次屏幕内存就少几兆,几次之后就会出现OutOfMemoryError,于是尝试了下把CursorAdapter换成BaseAdapter,结果就没有这个问题。具体原因尚不清楚,猜测是CursorAdapter配合Loader一起用时,有些回调方法保持的引用没有来得及移除掉。

于是想干脆把所有的CursorAdapter都换成BaseAdapter,然后自己在其内部封装一个Cursor来实现,但是这样一搞,以前项目中写的所有Adapter都要得重新写一遍,这工作量有点大了···

这时突然想到CursorAdapter其实也是继承于BaseAdapter,然后去简单翻看了一下CursorAdapter的源代码,想到个办法,干脆将其中的很多用不到的代码全部去掉,自己写了一个精简版的CursorAdapter,然后取个名字:CustomCursorAdapter.java, 再然后把原来所有继承 CursorAdapter的类 直接换成继承CustomCursorAdapter

嘿,这样一搞居然还真把问题给解决了,现在不管屏幕翻转多少次,都不会再出现OutOfMemoryError,噢耶!

CustomCursorAdapter.java
import android.content.Context;
import android.database.Cursor;
import android.provider.BaseColumns;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;


public abstract class CustomCursorAdapter extends BaseAdapter {


    protected Context mContext;
    private Cursor mCursor;


    public CustomCursorAdapter(Context context, Cursor cursor, int flag) {
        this(context, cursor);
    }


    public CustomCursorAdapter(Context context, Cursor cursor) {
        if (context == null) {
            throw new NullPointerException("context should not be null");
        }
        this.mContext = context;
        this.mCursor = cursor;
    }


    @Override
    public int getCount() {
        if (mCursor != null) {
            return mCursor.getCount();
        } else {
            return 0;
        }
    }


    @Override
    public Object getItem(int position) {
        if (mCursor != null) {
            mCursor.moveToPosition(position);
            return mCursor;
        } else {
            return null;
        }
    }


    @Override
    public long getItemId(int position) {
        if (mCursor != null) {
            if (mCursor.moveToPosition(position)) {
                return mCursor.getLong(mCursor.getColumnIndexOrThrow(BaseColumns._ID));
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (!mCursor.moveToPosition(position)) {
            throw new IllegalStateException("couldn't move cursor to position " + position);
        }
        View v;
        if (convertView == null) {
            v = newView(mContext, mCursor, parent);
        } else {
            v = convertView;
        }
        bindView(v, mContext, mCursor);
        return v;
    }


    public abstract View newView(Context context, Cursor cursor, ViewGroup view);


    public abstract void bindView(View view, Context context, Cursor cursor);


    public Cursor getCursor() {
        return mCursor;
    }


}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值