Android:MoveToNext() 出错

Android : Error on MoveToNext()

我正在尝试在 Android 上使用 SQLite 数据库在 table 上存储对象讨论 (ID, USER),即 (ID, ID2, USER)。

我已经设置了我的数据库,并在上面放了一些项目 (5)。我检查了 ADB SHELL 和 SQLITE3 命令。

当我想通过以下方法获取所有项目时:

public ArrayList<Discuss> getAllDiscuss(){
    ArrayList<Discuss> discussList = new ArrayList<Discuss>();
    Cursor cursor = bdd.query(TABLE_DISCUSS, new String[] {COL_DISCUSS_ID, COL_DISCUSS_ID_SERVER, COL_ID_OTHERUSER}, null, null, null, null, null);
    try {
        if (cursor.moveToFirst()) {
            do {
                discussList.add(cursorToDiscuss(cursor));
            } while (cursor.moveToNext());
        }
    } finally {
        try { cursor.close(); } catch (Exception ignore) {}
    }
    return discussList;
}

我有这个错误:

02-04 23:48:25.333: E/AndroidRuntime(2122): FATAL EXCEPTION: main
02-04 23:48:25.333: E/AndroidRuntime(2122): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gam/com.gam.MainActivity}: java.lang.IllegalStateException: attempt to re-open an already-closed object: android.database.sqlite.SQLiteQuery (mSql = SELECT ID, Id_Server, Id_OtherUser FROM Table_Discuss) 
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1955)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.app.ActivityThread.access0(ActivityThread.java:122)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1146)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.os.Looper.loop(Looper.java:137)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.app.ActivityThread.main(ActivityThread.java:4340)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at java.lang.reflect.Method.invokeNative(Native Method)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at java.lang.reflect.Method.invoke(Method.java:511)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at dalvik.system.NativeStart.main(Native Method)
02-04 23:48:25.333: E/AndroidRuntime(2122): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: android.database.sqlite.SQLiteQuery (mSql = SELECT ID, Id_Server, Id_OtherUser FROM Table_Discuss) 
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:33)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:82)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:160)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:143)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:175)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.database.AbstractCursor.moveToNext(AbstractCursor.java:243)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at com.gam.sqlite.GamAppSqliteBDD.getAllDiscuss(GamAppSqliteBDD.java:242)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at com.gam.MainActivity.onCreate(MainActivity.java:116)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.app.Activity.performCreate(Activity.java:4465)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
02-04 23:48:25.333: E/AndroidRuntime(2122):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1919)
02-04 23:48:25.333: E/AndroidRuntime(2122):     ... 11 more

GamAppSqliteBDD.java 文件的第 242 行是:

} while (cursor.moveToNext());

谁能帮我理解并解决这个错误?

如果我使用下面的代码,我也会出现这个错误:

    public ArrayList<Discuss> getAllDiscuss(){
        ArrayList<Discuss> discussList = new ArrayList<Discuss>();
        Cursor cursor = bdd.query(TABLE_DISCUSS, new String[] {COL_DISCUSS_ID, COL_DISCUSS_ID_SERVER, COL_ID_OTHERUSER}, null, null, null, null, null);
        try {
            if (cursor.moveToFirst()) {
//                do {
                    discussList.add(cursorToDiscuss(cursor));
                    discussList.add(cursorToDiscuss(cursor));
//                } while (cursor.moveToNext());
            }
        } finally {
            try { cursor.close(); } catch (Exception ignore) {}
        }
        return discussList;
    }

但是这次在第二行:discussList.add(cursorToDiscuss(cursor));

感谢您的阅读!

[不推荐] 我认为问题在于关闭游标。只需将 cursor.close() 放在评论中并再次 运行!!

//cursor.close()

[推荐]

错误在行

02-04 23:48:25.333: E/AndroidRuntime(2122): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: android.database.sqlite.SQLiteQuery (mSql = SELECT ID, Id_Server, Id_OtherUser FROM Table_Discuss) 

它说您正在尝试打开已经关闭的对象。在这种情况下,它是您正在使用的 cursor。即使在您关闭光标后,您的光标也可能在运行。

以正确的顺序获取代码将发挥作用!干杯

谢谢!你帮助我理解我的错误。我在我的方法 cursorToDiscuss() 中传递了我的光标,它是:

private Discuss cursorToDiscuss(Cursor c){
    if (c.getCount() == 0)
        return null;
    c.moveToFirst();
    Discuss discuss = new Discuss();
    discuss.setId(c.getInt(NUM_COL_DISCUSS_ID));
    discuss.setIdServer(c.getInt(NUM_COL_DISCUSS_ID_SERVER));
    discuss.setIdOtherUser(c.getInt(NUM_COL_ID_OTHERUSER));
    c.close();
    return discuss;
}

并且在这个方法中,我在 return 我的对象之前关闭了光标。

我在 :

中修改了我的方法 getAllDiscuss()
public ArrayList<Discuss> getAllDiscuss(){
    ArrayList<Discuss> discussList = new ArrayList<Discuss>();
    Cursor cursor = bdd.query(TABLE_DISCUSS, new String[] {COL_DISCUSS_ID, COL_DISCUSS_ID_SERVER, COL_ID_OTHERUSER}, null, null, null, null, null);
    try {
        if (cursor.moveToFirst()) {
            do {
                Discuss discuss = new Discuss();
                discuss.setId(cursor.getInt(NUM_COL_DISCUSS_ID));
                discuss.setIdServer(cursor.getInt(NUM_COL_DISCUSS_ID_SERVER));
                discuss.setIdOtherUser(cursor.getInt(NUM_COL_ID_OTHERUSER));
                discussList.add(discuss);
            } while (cursor.moveToNext());
        }
    } finally {
        try { cursor.close(); } catch (Exception ignore) {}
    }
    return discussList;
}

终于成功了!

感谢您的帮助:)