Android:MoveToNext()出错

时间:2015-02-04 23:07:35

标签: android sqlite cursor

我试图在Android上使用SQLite数据库来存储对象(ID,用户)的对象讨论(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.access$600(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));

感谢您的阅读!

2 个答案:

答案 0 :(得分:0)

[ 不推荐 ]我认为问题在于关闭游标。只需将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。即使关闭光标,光标也可能正常运行。

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

答案 1 :(得分:0)

谢谢!你帮我理解我的错误。我将光标传递给我的方法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;
}

在这个方法中,我先关闭光标然后返回我的对象​​。

我修改了我的方法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;
}

它终于有效了!

感谢您的帮助:)