在LoaderCallbacks中使用CursorAdapter造成的内存泄露问题
2012-09-14 14:52
441 查看
今天在项目中被一个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
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; } }
相关文章推荐
- Android开发中使用Handler类造成的内存泄露问题
- 解决Android使用Handler造成内存泄露问题
- 关于使用json库造成的内存泄露问题
- tomcat中使用Quartz造成内存泄露的问题解决
- Android使用Handler造成的内存泄露问题的解决
- 使用Canvas、Bitmap时易犯的内存泄露问题
- Mysql: Connect/C++ 使用过程中发现返回 std::string 造成的内存泄露
- Android 性能优化之使用MAT分析内存泄露问题
- Android中使用Handler造成内存泄露的分析和解决
- Android中使用Handler造成内存泄露的分析和解决
- Android中使用Handler造成内存泄露的分析和解决
- Android中使用Handler造成内存泄露的分析和解决
- 使用WinDBG调试内存泄露的问题
- 使用block造成的内存泄露和block和delegate的区别
- android中使用Cursor时防止内存泄露的几个方面
- Android中使用Handler造成内存泄露的分析和解决
- Android中使用Handler造成内存泄露的分析和解决
- Android中使用Handler造成内存泄露的分析和解决
- Android中使用Handler造成内存泄露的分析和总结
- 多线程 DLL 回调函数问题,当应用程序退出时,有些操作并未完成,造成程序内存泄露,如何解决呢