0

我正在尝试为高分表实现 SQLite 数据库。我只是在测试它,看看我的数据库创建、插入和选择是否正在使用以下代码。我正在尝试将第一行插入数据库,然后立即从中提取并将值显示到 TextViews。所有硬编码都是为了测试目的,以使数据库正常工作。

我在以下几行中收到 IllegalStateException 。我已在相应行的错误中进行了评论。

任何关于代码结构的额外建议也非常感谢。

先感谢您!

高分.java

public class Highscores extends Activity {

    DatabaseHelper dh;
    SQLiteDatabase db;
    int percentages;
    long scores;
    TableLayout table;
    TableRow rowHeader, row1, row2, row3, row4, row5, row6, row7, row8, row9, row10;
    TextView rank, percentage, score;
    Button btn1;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.highscoresmain);

        dh = new DatabaseHelper(this);
        db = dh.openDB();
        long x = 11;
        int y = 22;
        dh.insert(x, y);
        percentages = dh.getPercentage(db);  //Line 45
        scores = dh.getScore(db);

        Button btn1 = (Button)findViewById(R.id.homeBtn);

        TextView rank = (TextView)findViewById(R.id.rank);
        TextView percentage = (TextView)findViewById(R.id.percentage);
        TextView score = (TextView)findViewById(R.id.score);

        TextView r1r = (TextView)findViewById(R.id.r1r);
        TextView r1p = (TextView)findViewById(R.id.r1p);
        TextView r1s = (TextView)findViewById(R.id.r1s);

        rank.setText("Rank Column - TEST");
        percentage.setText("Percentage Column - TEST ");
        score.setText("Score Column - Test");
        r1r.setText("test..rank");
        r1p.setText(percentages);
        r1s.setText("test..score");

        table = (TableLayout)findViewById(R.id.tableLayout);

              dh.closeDB(db);
         }
       }

数据库助手.java

public class DatabaseHelper extends SQLiteOpenHelper { 

    SQLiteDatabase db;

    private static final String TABLE = "HighscoresList"; 
    public static DatabaseHelper mSingleton = null;

    // Table columns names. 
    private static final String RANK = "_id"; 
    private static final String SCORE = "score"; 
    private static final String PERCENTAGE = "percentage";

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

    public synchronized static DatabaseHelper getInstance(Context context) {
        if(mSingleton == null) {
            mSingleton = new DatabaseHelper(context.getApplicationContext());
        }
        return mSingleton;
    }

    public SQLiteDatabase openDB() {
        db = this.getWritableDatabase();
        return db;
    }

          //I am using hard coded numbers in the below 2 methods for testing purposes.
public long getScore(SQLiteDatabase db) {
    Cursor c = db.rawQuery("SELECT " + SCORE + " FROM " + TABLE + " WHERE " + SCORE + " = " + 11 + ";", null);  //Line 45
    long i = 0;
    if(c.getCount() != 0) {
           c.moveToFirst();
           int columnIndex = c.getInt(c.getColumnIndex("SCORE"));
           if(columnIndex != -1) {
               i = c.getLong(columnIndex);
           } else { 
               i = 999; 
           }
    } else {
        i = 555;
    }
    c.close();
    return i;
}

public int getPercentage(SQLiteDatabase db) {
    Cursor c = db.rawQuery("SELECT " + PERCENTAGE + " FROM " + TABLE + " WHERE " + PERCENTAGE + " = " + 22 + ";", null);
    int i = 0;
    if(c.getCount() != 0) {
           c.moveToFirst();
           int columnIndex = c.getInt(c.getColumnIndex("PERCENTAGE"));
           if(columnIndex != -1) {
               i = c.getInt(columnIndex);
           } else { 
               i = 999; 
           }
    } else {
        i = 555;
    }
    c.close();
    return i;

}

          //Insert new record.
    public long insert(long score, int percentage) {
        ContentValues values = new ContentValues();
        values.put(SCORE, score);
        values.put(PERCENTAGE, percentage);

        return db.insert(TABLE, null, values);
          }
}

LogCat 输出

01-03 15:39:13.952: E/AndroidRuntime(938): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test/com.example.test.Highscores}: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
01-03 15:39:13.952: E/AndroidRuntime(938):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
01-03 15:39:13.952: E/AndroidRuntime(938):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
01-03 15:39:13.952: E/AndroidRuntime(938):  at android.app.ActivityThread.access$600(ActivityThread.java:141)
01-03 15:39:13.952: E/AndroidRuntime(938):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
01-03 15:39:13.952: E/AndroidRuntime(938):  at android.os.Handler.dispatchMessage(Handler.java:99)
01-03 15:39:13.952: E/AndroidRuntime(938):  at android.os.Looper.loop(Looper.java:137)
01-03 15:39:13.952: E/AndroidRuntime(938):  at android.app.ActivityThread.main(ActivityThread.java:5039)
01-03 15:39:13.952: E/AndroidRuntime(938):  at java.lang.reflect.Method.invokeNative(Native Method)
01-03 15:39:13.952: E/AndroidRuntime(938):  at java.lang.reflect.Method.invoke(Method.java:511)
01-03 15:39:13.952: E/AndroidRuntime(938):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
01-03 15:39:13.952: E/AndroidRuntime(938):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
01-03 15:39:13.952: E/AndroidRuntime(938):  at dalvik.system.NativeStart.main(Native Method)
01-03 15:39:13.952: E/AndroidRuntime(938): Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
01-03 15:39:13.952: E/AndroidRuntime(938):  at android.database.CursorWindow.nativeGetLong(Native Method)
01-03 15:39:13.952: E/AndroidRuntime(938):  at android.database.CursorWindow.getLong(CursorWindow.java:507)
01-03 15:39:13.952: E/AndroidRuntime(938):  at android.database.CursorWindow.getInt(CursorWindow.java:574)
01-03 15:39:13.952: E/AndroidRuntime(938):  at android.database.AbstractWindowedCursor.getInt(AbstractWindowedCursor.java:69)
01-03 15:39:13.952: E/AndroidRuntime(938):  at com.example.test.DatabaseHelper.getPercentage(DatabaseHelper.java:67)
01-03 15:39:13.952: E/AndroidRuntime(938):  at com.example.test.Highscores.onCreate(Highscores.java:45)
01-03 15:39:13.952: E/AndroidRuntime(938):  at android.app.Activity.performCreate(Activity.java:5104)
01-03 15:39:13.952: E/AndroidRuntime(938):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
01-03 15:39:13.952: E/AndroidRuntime(938):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
01-03 15:39:13.952: E/AndroidRuntime(938):  ... 11 more

编辑: 我更新了我的getScore()getPercentage()方法。无论如何,我仍然使用了一些硬编码的数字,所以我确切地知道发生了什么,但程序仍然崩溃。似乎 if-else 语句应该将 i 设置为 555 而不是崩溃,但事实并非如此。

我也更新了 LogCat 输出。

4

2 回答 2

3

我没有看到任何数据库初始化代码覆盖 onCreate 但它说您的列在表中不存在再次检查它的名称或检查表。还要养成使用完光标后关闭光标的习惯。否则,当您没有关闭前一个游标时,数据库将抛出错误。

刚刚注意到您在将其定义为时使用“PERCENTAGE”的错误

PERCENTAGE = "percentage";

所以在使用定义的变量时要保持一致。

Android - SQLite Cursor getColumnIndex() 区分大小写?

public int getPercentage(SQLiteDatabase db) {
    Cursor c = db.rawQuery("SELECT " + PERCENTAGE + " FROM " + TABLE + " WHERE " + PERCENTAGE + " = " + 22 + ";", null);
    int i = 0;
    if (c.moveToFirst())
    {
        int colIdx = c.getColumnIndex(PERCENTAGE);
        if (colIdx != -1) // Column exists
            i = c.getInt(colIdx);  //Line 54
    }
    c.close();
    return i;
}
于 2013-01-03T14:58:58.620 回答
2

基于大卫的评论:

public int getPercentage(SQLiteDatabase db) {
     Cursor c = db.rawQuery("SELECT " + PERCENTAGE + " FROM " + TABLE + " WHERE " + PERCENTAGE + " = " + 22 + ";", null);
     if(c.getCount() != 0){
            c.moveToFirst();
            int i = c.getInt(c.getColumnIndex(PERCENTAGE));  //Line 54
            return i;
     } else { return 0 }
}

始终如一地使用该常量,并确保它与您的 sqllite DB 完全相同。显然 getColumnIndex 区分大小写 ;)

于 2013-01-03T14:50:35.140 回答