Android,无法重新打开已关闭的查询

时间:2015-09-30 19:48:07

标签: android database sqlite cursor

我正在尝试从SQLite数据库中读取数据,以便CursorAdapter可以将其格式化为我的列表视图项,但是当我尝试使用rawQuery时我收到错误,说我试图重新打开已经封闭的对象。我已经研究过这个错误,这个错误主要发生在人们在关闭游标后尝试使用他们的游标对象时,但我的游标关闭是在方法结束时,每次调用都会创建一个新的数据库。 close()方法已被删除,但无济于事。我已经包括了相关的课程。

MainActivityFragment

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    //Primary View Inflator
    final View rootView = inflater.inflate(R.layout.fragment_main, container, false);

    //Databse instatiation
    final MySQLiteHelper mDbHelper = new MySQLiteHelper(getActivity());

button2.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

        if((noteTitle.getText().toString().trim()).equals("")){
            Toast.makeText(getActivity().getBaseContext(), "No Title Specified", Toast.LENGTH_SHORT).show();
        }else {
            String noteTitleString = noteTitle.getText().toString();
            String noteBodyString = noteBody.getText().toString();

            Toast.makeText(getActivity().getBaseContext(), "Added: " + noteTitleString, Toast.LENGTH_SHORT).show();

            //Clear text fields and hide keyboard
            noteTitle.getText().clear();
            noteBody.getText().clear();
            final InputMethodManager imm = (InputMethodManager)
                    getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);

            //Write new row into database and refresh listview
            addNotes(mDbHelper, noteTitleString, noteBodyString);
            readNotes(rootView);
        }
        }
    });
}

private void addNotes(MySQLiteHelper mDbHelper, String title, String body){

    // Gets the data repository in write mode
    SQLiteDatabase db = mDbHelper.getWritableDatabase();

// Create a new map of values, where column names are the keys
    ContentValues values = new ContentValues();
    values.put(FeedEntry.COLUMN_NAME_TITLE, title);
    values.put(FeedEntry.COLUMN_NAME_BODY, body);

// Insert the new row, returning the primary key value of the new row
    db.insert(
            FeedEntry.TABLE_NAME,
            null,
            values);

//        db.close();
}

private void readNotes(View rootView){

    MySQLiteHelper mDbHelper = new MySQLiteHelper(getActivity());
    SQLiteDatabase db = mDbHelper.getWritableDatabase(); //changed from readable

    // Query for items from the database and get a cursor back
    Cursor notesCursor = db.rawQuery("SELECT  * FROM notes", null);

    // Find ListView to populate
    ListView notelv = (ListView) rootView.findViewById(R.id.note_list_view);
    // Setup cursor adapter using cursor from last step
    final NotesListAdapter noteAdapter = new NotesListAdapter(rootView.getContext(), notesCursor, 0);
    //// Attach cursor adapter to the ListView
    notelv.setAdapter(noteAdapter);

    notesCursor.close();

}

MySQLiteHelper

public class MySQLiteHelper extends SQLiteOpenHelper {

private static final String TEXT_TYPE = " TEXT";
private static final String INT_TYPE = " INTEGER";
private static final String COMMA_SEP = ",";
private static final String SQL_CREATE_ENTRIES =
        "CREATE TABLE " + FeedEntry.TABLE_NAME + " (" +
                FeedEntry._ID + " INTEGER PRIMARY KEY," +
                FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE + COMMA_SEP +
                FeedEntry.COLUMN_NAME_BODY + TEXT_TYPE +
        " )";

private static final String SQL_DELETE_ENTRIES =
        "DROP TABLE IF EXISTS " + FeedEntry.TABLE_NAME;



// If you change the database schema, you must increment the database version.
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "FeedReader.db";

public MySQLiteHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
    db.execSQL(SQL_CREATE_ENTRIES);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // This database is only a cache for online data, so its upgrade policy is
    // to simply to discard the data and start over
    db.execSQL(SQL_DELETE_ENTRIES);
    onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    onUpgrade(db, oldVersion, newVersion);
}
}

错误堆栈

Process: com.example.ggould.scribble, PID: 8408
java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT  * FROM notes
        at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
        at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:58)
        at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:152)
        at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:124)
        at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:214)
        at android.widget.CursorAdapter.getView(CursorAdapter.java:245)
        at android.widget.AbsListView.obtainView(AbsListView.java:2344)
        at android.widget.ListView.measureHeightOfChildren(ListView.java:1270)
        at android.widget.ListView.onMeasure(ListView.java:1182)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
        at android.support.v7.internal.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:124)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
        at android.support.v7.internal.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:393)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
        at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
        at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
        at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463)
        at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
        at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2560)
        at android.view.View.measure(View.java:17430)
        at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2001)
        at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1166)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1372)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5779)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
        at android.view.Choreographer.doCallbacks(Choreographer.java:580)
        at android.view.Choreographer.doFrame(Choreographer.java:550)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

1 个答案:

答案 0 :(得分:0)

我实际上最终会发现任何遇到此问题的人。

我从readNotes()方法中删除了这一行,因为它实际上创建了与数据库的第二个连接,并且当一个接一个地调用add和read方法时,数据库将只识别第一个请求并完全删除另一个连接。然后我传入mDbHelper作为参数。

MySQLiteHelper mDbHelper = new MySQLiteHelper(getActivity());

我还必须删除此行,因为光标在CursorAdapter完成其进程之前关闭,从而引发错误。

notesCursor.close();