IllegalStateException:尝试重新查询已经关闭的游标

时间:2014-02-14 03:58:46

标签: android sqlite android-cursorloader

我的应用程序在重新打开时不断崩溃。问题在于这个特定的活动,它是一个使用我编写的单独帮助程序类从sql数据库填充的listview。

我使用不推荐使用的cursormanager,不知道如何使用cursorloader。任何有关如何进行切换的帮助都将非常感激。下面是导致问题的活动的代码。

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.database.Cursor;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class ExerciseCategories extends Activity {

private static final int INSERT_ID = Menu.FIRST;
private static final int DELETE_ID = Menu.FIRST+1;
private static final int URL_LOADER = 0;
private CategoryDbAdapter mDbHelper;
private String s;
ListView listview;
private Long mRowId; 
Cursor cursor; 

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.exercise_categories);
    mDbHelper = new CategoryDbAdapter(this);
    mDbHelper.open();
    fillData();
    registerForContextMenu(listview);

}

@SuppressWarnings("deprecation")
private void fillData() {       
    cursor = mDbHelper.fetchAllCategories();
    startManagingCursor(cursor);
    String[] from = new String[] { CategoryDbAdapter.KEY_CATEGORY };
    int[] to = new int[] { R.id.text1 };
    SimpleCursorAdapter categories = new SimpleCursorAdapter(this,
            R.layout.category_row, cursor, from, to);
    listview = (ListView) findViewById(R.id.category_list);
    listview.setAdapter(categories);
    mDbHelper.close();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    menu.add(0, INSERT_ID, 0, R.string.menu_insert);
    return true;
}

@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
    switch (item.getItemId()) {
    case INSERT_ID:
        LayoutInflater li = LayoutInflater.from(this);
        View promptsView = li.inflate(R.layout.promptdialog, null);
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
                this);
        alertDialogBuilder.setView(promptsView);
        final EditText userInput = (EditText) promptsView
                .findViewById(R.id.editTextDialogUserInput);
        alertDialogBuilder
                .setCancelable(false)
                .setPositiveButton("OK",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                    int id) {
                                s = userInput.getText().toString();
                                mDbHelper.open();
                                mDbHelper.newCategory(s);
                                fillData(); 
                            }
                        })
                .setNegativeButton("Cancel",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog,
                                    int id) {
                                dialog.cancel();
                            }
                        });

        AlertDialog alertDialog = alertDialogBuilder.create();
        alertDialog.show();
    }

    return super.onMenuItemSelected(featureId, item);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
        ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    menu.add(0, DELETE_ID, 0, R.string.menu_delete);
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    switch(item.getItemId()) {
        case DELETE_ID:
            mDbHelper.open(); 
            AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
            mDbHelper.deleteCategory(info.id);
            fillData();
            return true;
    }
    return super.onContextItemSelected(item);
}

继承人帮助班:

public class CategoryDbAdapter {

static final String KEY_ROWID = "_id";
static final String KEY_CATEGORY = "category";

private static final String TAG = "CategoriesDbAdapter";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;

private static final String DATABASE_CREATE = "create table categories (_id integer primary key autoincrement, "
        + "category text not null);";

private static final String DATABASE_NAME = "data";
private static final String DATABASE_TABLE = "categories";
private static final int DATABASE_VERSION = 1;

private final Context mCtx;

private static class DatabaseHelper extends SQLiteOpenHelper {

    DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DATABASE_CREATE);
        String[] string = { "Back", "Biceps", "Chest", "Core", "Legs",
                "Shoulder", "Triceps" };
        for (int i = 0; i < string.length; i++) {
            ContentValues values = new ContentValues();
            values.put(KEY_CATEGORY, string[i]);
            db.insert(DATABASE_TABLE, null, values);
        }
    }


    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS categories");
        onCreate(db);
    }
}

public CategoryDbAdapter(Context ctx) {
    this.mCtx = ctx;
}

public CategoryDbAdapter open() throws SQLException {
    mDbHelper = new DatabaseHelper(mCtx);
    mDb = mDbHelper.getWritableDatabase();
    return this;
}

public void close() {
    mDbHelper.close();
}

public Cursor fetchAllCategories() {

    return mDb.query(DATABASE_TABLE,
            new String[] { KEY_ROWID, KEY_CATEGORY }, null, null, null,
            null, null);
}

public long newCategory(String category) {
    ContentValues initialValues = new ContentValues();
    initialValues.put(KEY_CATEGORY, category);
    return mDb.insert(DATABASE_TABLE, null, initialValues);
}

public boolean deleteCategory(long rowId) {

    return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}

public Cursor fetchCategory(long rowId) throws SQLException {

    Cursor mCursor =

    mDb.query(true, DATABASE_TABLE,
            new String[] { KEY_ROWID, KEY_CATEGORY }, KEY_ROWID + "="
                    + rowId, null, null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;

}

public boolean updateCategory(long rowId, String title) {
    ContentValues args = new ContentValues();
    args.put(KEY_CATEGORY, title);
    return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}

}

1 个答案:

答案 0 :(得分:0)

至于切换到Loader界面,我个人使用,强烈推荐这里提供的cwac-loaderex库:https://github.com/commonsguy/cwac-loaderex

它有一个非常简单的界面和很棒的文档/代码示例。