簡體   English   中英

在sqlite上插入時SQLite android NullPointerException

[英]SQLite android NullPointerException when inserting on sqlite

我知道存在類似的問題,但是我發現的所有問題都與沒有SQLiteDatabase實例有關。

創建數據庫的onCreate方法中的表定義之一如下所示:

db.execSQL("CREATE TABLE offers(" +
            "    game_state_id   INTEGER NOT NULL REFERENCES game_states (id)," +
            "    city_id         INTEGER NOT NULL REFERENCES cities (id)," +
            "    item_id         INTEGER NOT NULL REFERENCES items (id)," +
            "    sell_price      INTEGER NOT NULL," +
            "    buy_price       INTEGER NOT NULL," +
            "    amount          INTEGER NOT NULL DEFAULT 0," +
            "    UNIQUE (game_state_id, city_id, item_id)" +
            ")");

而且工作正常,數據庫看起來不錯。

public long createGameState() {
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put("name", "default");
    values.put("current_city_id", getInitialCityId());
    // it could return -1 if insert didn't work
    long res = db.insert("game_states", null, values);

    List<City> cities = loadCities();
    List<Item> items = loadItems();
    Log.d("Kupiec", "Itemki: "+String.valueOf(items.size())+" | Miasta: "+String.valueOf(cities.size()));

    for (City city : cities) {
        for (Item item : items) {
            ContentValues values2 = new ContentValues();
            values2.put("item_id", item.id);
            values2.put("city_id", city.id);
            values2.put("game_state_id", res);
            values2.put("buy_price", Utils.getRandom(100, 125));
            values2.put("sell_price", Utils.getRandom(75, 100));
            values2.put("amount", Utils.getRandom(15, 30));
            Log.d("Kupiec", "offer_values: "+values2.toString());
            db.insert("offers", null, values2);
        }
    }

    db.close();
    return res;
}

有趣的是,第一次插入到game_states表中可以正常工作,但是在循環中的第一次插入時會中斷。

06-12 13:28:03.872      630-630/com.mippit.kupiec E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalStateException: Could not execute method of the activity
    at android.view.View$1.onClick(View.java:3044)
    at android.view.View.performClick(View.java:3511)
    at android.view.View$PerformClick.run(View.java:14105)
    at android.os.Handler.handleCallback(Handler.java:605)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4424)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at android.view.View$1.onClick(View.java:3039)
    at android.view.View.performClick(View.java:3511)
    at android.view.View$PerformClick.run(View.java:14105)
    at android.os.Handler.handleCallback(Handler.java:605)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4424)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
    at android.database.sqlite.SQLiteStatement.releaseAndUnlock(SQLiteStatement.java:290)
    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:115)
    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1718)
    at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1591)
    at com.mippit.kupiec.Repository.createGameState(Repository.java:182)
    at com.mippit.kupiec.Repository.createNewGame(Repository.java:153)
    at com.mippit.kupiec.MainActivity.clicked_new_game(MainActivity.java:42)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at android.view.View$1.onClick(View.java:3039)
    at android.view.View.performClick(View.java:3511)
    at android.view.View$PerformClick.run(View.java:14105)
    at android.os.Handler.handleCallback(Handler.java:605)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4424)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    at dalvik.system.NativeStart.main(Native Method)

這是怎么回事? 出現此錯誤的第182行是db.insert("offers", null, values2);

我得到了很好的答案,但是作者刪除了它,可能是因為他得到了2張贊成票(不是來自我!)。 如果某人可以將其歸還,請這樣做,我很高興將其標記為已接受。

最后,正確的答案是try {...} catch {}NullPointerException並再次加載數據庫。 我不明白為什么會這樣,因為我認為在我明確說出db.close()之前,db將是打開的,但是它正在工作。

我看到的問題是,您已經在具有不同表的數據庫中插入了值,並且沒有關閉它就試圖再次插入。 所以那里有沖突。 替換您的for循環語句

db.insert("offers", null, values2);

db.insertWithOnConflict("table name", null, "values", SQLiteDatabase.CONFLICT_IGNORE); 

這是因為您的game_state_id必須是唯一的。 您將繼續為其分配與上面相同的值res 因此,它將在第一次運行,但在其他任何時間都不會...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM