我正在尝试将 CursorLoader 与 CursorTreeAdapter 一起使用,但遇到了一个我无法弄清楚的问题。(如果您有这方面的工作示例,请随意跳过其余部分并将其附在下面。我将非常感谢)我第一次打开一个组时,一切正常。如果我随后关闭并重新打开该组,则会收到溢出错误。这是错误:
V/SpellBook(29520): Activity being created
D/SpellBook(29520): onCreateLoader for id 123456
V/SpellBook(29520): Resuming
V/SpellBook(29520): Processing query for uri content://com.zalzala.spellbook.SpellProvider/levels/bard
D/SpellBook(29520): onLoadFinished() for id 123456
D/SpellBook(29520): onCreateLoader for id 3
V/SpellBook(29520): Processing query for uri content://com.zalzala.spellbook.SpellProvider/class/bard/3
D/SpellBook(29520): onLoadFinished() for id 3
这里一切都很好。到目前为止,我已经打开了活动并打开了第 3 组。如果我关闭第 3 组并再次打开它,会发生以下情况:
D/SpellBook(29520): onLoadFinished() for id 3
D/SpellBook(29520): onLoadFinished() for id 3
D/SpellBook(29520): onLoadFinished() for id 3
D/SpellBook(29520): onLoadFinished() for id 3
D/SpellBook(29520): onLoadFinished() for id 3
(... and a lot more of these)
E/AndroidRuntime(29520): FATAL EXCEPTION: main
E/AndroidRuntime(29520): java.lang.StackOverflowError
E/AndroidRuntime(29520): at java.util.HashMap.get(HashMap.java:302)
E/AndroidRuntime(29520): at android.database.sqlite.SQLiteCursor.getColumnIndex(SQLiteCursor.java:355)
E/AndroidRuntime(29520): at android.database.CursorWrapper.getColumnIndex(CursorWrapper.java:67)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment$MyExpandableListAdapter.getChildrenCursor(SpellListView.java:216)
E/AndroidRuntime(29520): at android.widget.CursorTreeAdapter.getChildrenCursorHelper(CursorTreeAdapter.java:106)
E/AndroidRuntime(29520): at android.widget.CursorTreeAdapter.setChildrenCursor(CursorTreeAdapter.java:159)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment.onLoadFinished(SpellListView.java:183)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment.onLoadFinished(SpellListView.java:1)
E/AndroidRuntime(29520): at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:413)
E/AndroidRuntime(29520): at android.support.v4.app.LoaderManagerImpl.initLoader(LoaderManager.java:547)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment$MyExpandableListAdapter.getChildrenCursor(SpellListView.java:217)
E/AndroidRuntime(29520): at android.widget.CursorTreeAdapter.getChildrenCursorHelper(CursorTreeAdapter.java:106)
E/AndroidRuntime(29520): at android.widget.CursorTreeAdapter.setChildrenCursor(CursorTreeAdapter.java:159)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment.onLoadFinished(SpellListView.java:183)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment.onLoadFinished(SpellListView.java:1)
E/AndroidRuntime(29520): at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:413)
E/AndroidRuntime(29520): at android.support.v4.app.LoaderManagerImpl.initLoader(LoaderManager.java:547)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment$MyExpandableListAdapter.getChildrenCursor(SpellListView.java:217)
E/AndroidRuntime(29520): at android.widget.CursorTreeAdapter.getChildrenCursorHelper(CursorTreeAdapter.java:106)
E/AndroidRuntime(29520): at android.widget.CursorTreeAdapter.setChildrenCursor(CursorTreeAdapter.java:159)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment.onLoadFinished(SpellListView.java:183)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment.onLoadFinished(SpellListView.java:1)
E/AndroidRuntime(29520): at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:413)
E/AndroidRuntime(29520): at android.support.v4.app.LoaderManagerImpl.initLoader(LoaderManager.java:547)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment$MyExpandableListAdapter.getChildrenCursor(SpellListView.java:217)
E/AndroidRuntime(29520): at android.widget.CursorTreeAdapter.getChildrenCursorHelper(CursorTreeAdapter.java:106)
E/AndroidRuntime(29520): at android.widget.CursorTreeAdapter.setChildrenCursor(CursorTreeAdapter.java:159)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment.onLoadFinished(SpellListView.java:183)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment.onLoadFinished(SpellListView.java:1)
E/AndroidRuntime(29520): at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:413)
E/AndroidRuntime(29520): at android.support.v4.app.LoaderManagerImpl.initLoader(LoaderManager.java:547)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment$MyExpandableListAdapter.getChildrenCursor(SpellListView.java:217)
E/AndroidRuntime(29520): at android.widget.CursorTreeAdapter.getChildrenCursorHelper(CursorTreeAdapter.java:106)
E/AndroidRuntime(29520): at android.widget.CursorTreeAdapter.setChildrenCursor(CursorTreeAdapter.java:159)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment.onLoadFinished(SpellListView.java:183)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment.onLoadFinished(SpellListView.java:1)
E/AndroidRuntime(29520): at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:413)
E/AndroidRuntime(29520): at android.support.v4.app.LoaderManagerImpl.initLoader(LoaderManager.java:547)
E/AndroidRuntime(29520): at com.zalzala.spellbook.SpellListView$ExpandableListCursorLoaderFragment$MyExpandableListAdapter.getChildrenCursor(SpellListView.java:217)
E/AndroidRuntime(29520): at android.widget.CursorTreeAdapter.getChildrenCursorHelper(CursorTreeAdapter.ja
W/ActivityManager( 6887): Force finishing activity com.zalzala.spellbook/.SpellListView
因此,由于某种原因,在重新打开组时,子光标会一遍又一遍地调用 onLoadFinished()。
这是我的加载器实现:
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// TODO Auto-generated method stub
Log.d(Spellbook.TAG,"onCreateLoader for id "+id);
if (id <123456){
Uri spellUri = Uri.withAppendedPath(SpellProvider.CONTENT_URI, "class");
spellUri = Uri.withAppendedPath(spellUri, mCLASS);
spellUri = ContentUris.withAppendedId(spellUri, id);
return new CursorLoader(getActivity(), spellUri, null, null, null, null);
}else {
//get group cursor
Uri groupUri = Uri.withAppendedPath(SpellProvider.CONTENT_URI, "levels");
groupUri = Uri.withAppendedPath(groupUri, mCLASS);
return new CursorLoader(getActivity(), groupUri, null, null, null, null);
}
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// TODO Auto-generated method stub
int id = loader.getId();
Log.d(Spellbook.TAG,"onLoadFinished() for id "+id);
if (id < 123456){
//child cursor
((CursorTreeAdapter) mAdapter).setChildrenCursor(id, data);
} else {
((CursorTreeAdapter) mAdapter).setGroupCursor(data);
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
// TODO Auto-generated method stub
int id = loader.getId();
Log.d(Spellbook.TAG,"onLoaderReset() for id "+id);
if (id < 123456){
//child cursor
((CursorTreeAdapter) mAdapter).setChildrenCursor(id, null);
} else {
((CursorTreeAdapter) mAdapter).setGroupCursor(null);
}
}
我使用将自动重新查询指定为 false 的构造函数调用 CursorTreeAdapter。
public class MyExpandableListAdapter extends CursorTreeAdapter {
public MyExpandableListAdapter(Cursor cursor, Context context) {
super(cursor, context, false); //do not auto requery. pretty sure CursorLoader needs this.
}
@Override
protected Cursor getChildrenCursor(Cursor groupCursor) {
// Given the group, we return a cursor for all the children within that group
int id = groupCursor.getInt(groupCursor.getColumnIndex(SpellDbAdapter.KEY_LEVEL));
getLoaderManager().initLoader(id, null, ExpandableListCursorLoaderFragment.this);
return null;
}
谢谢你的帮助!