我有一个CursorAdapter
的实现,我正在使用Loader
到ListFragment
。除了下面的问题,这工作正常。它包含以下代码。每行包含一个复选框,用户可以在其中选择项目。操作栏上有一个删除按钮,允许用户删除所选项目。这是通过我ContentProvider
的实施实现的。
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
//some logic
this.cursor = cursor; //class variable assignment
}
void deleteStuff() {
if (cursor == null) {
return;
}
if (checkedItems == null || checkedItems.size()==0) { //A Sparse boolean array which saves the positions of items the user selected
return;
}
final SparseIntArray checkedKeys = new SparseIntArray(); //positions of selected items
final SparseLongArray checkedIds = new SparseLongArray(); //ids of the items at the resp keys
for (int i = 0; i < checkedItems.size(); i++) {
final int checkedItemKey = checkedItems.keyAt(i);
checkedKeys.append(i, checkedItemKey);
cursor.moveToPosition(checkedItemKey); //the line at which it fails!!!!!!!!
checkedItemIds.append(checkedItemKey, Long.parseLong(c.getString(0)));
}
for (int i = 0; i < checkedItems.size(); i++) {
myContentProvider.delete(uri, selection, args); //not putting the code for these 3 variables as not required
}
}
以下是ContentProvider
中的相应功能:
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = sqlitehelper.getWritableDatabase();
int rowsDeleted = sqlDB.delete(TJItemTable.TABLE_NAME, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}
当我选择多个项目并删除时,它第一次正常工作并完成它应该做的事情。但是,现在如果我再选择一个或多个项目,再次点击删除,则会在第XX行失败。
我在 LogCat 中遇到的错误是java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT id as _id, name, value FROM stufftable WHERE (value=?)
。它失败的行是:cursor.moveToPosition(checkedItemKey)
我确实看了this,并明白我将光标置于关闭状态或不稳定状态。但是,我无法想到任何可以解决我的问题的事情。我做错了什么?
注意:我在getContext().getContentResolver().notifyChange(uri, null)
中呼叫ContentProvider.delete()
,我认为,Loader
会通知光标。我还试着把this.notifyDataSetChanged()
放在最后,没有任何运气。
答案 0 :(得分:0)
每次输入时都在deleteStuff()中创建一个新的Cursor,而不是使用newView中的一个,它会搜索您要删除的条目。 (这应该有用)
您也可以尝试使用bindView中的游标,但我不确定这是否可行。
答案 1 :(得分:0)
更新:我终于以更简单的方式做到了这一点。我用checkBox()中的CheckBox.setOnCheckedChangeListener()内部的位置填充checkedItems。我将其更改为包含要删除的项目的ID而不是获取位置,然后使用位置的光标:)。所以在delete()中我已经准备好删除了Ids,而且我不必在这里弄乱光标。这符合我的愿望。我希望我早点想到这个,然后我不必在这里发布这个问题。我希望这有助于某人!