【问题标题】:Cursors, SQLite, and queries游标、SQLite 和查询
【发布时间】:2014-11-15 12:03:58
【问题描述】:

我在我的应用程序中实现了一个 sqlitedatabase,并且在启动时我不断收到 IllegalStateException。

09-21 22:48:26.749  15762-16277/nz.co.exium.panther E/AndroidRuntime﹕ FATAL EXCEPTION: SyncAdapterThread-2
java.lang.IllegalStateException: Couldn't read row 0, col 4 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
        at android.database.CursorWindow.nativeGetString(Native Method)
        at android.database.CursorWindow.getString(CursorWindow.java:438)
        at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
        at android.database.CursorWrapper.getString(CursorWrapper.java:114)
        at nz.co.exium.panther.sync.PantherSyncAdapter.getRegistrationId(PantherSyncAdapter.java:269)
        at nz.co.exium.panther.sync.PantherSyncAdapter.onPerformSync(PantherSyncAdapter.java:64)
        at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:254)

我相信这是由于查询返回了一个相当空的表(自动递增的 _ID 除外),然后当我尝试从游标中获取字符串时。

String registrationID = "";
    Uri uri = CustomerEntry.CONTENT_URI;
    Cursor cursor = mContext.getContentResolver().query(uri, CUSTOMER_PROJECTION, null, null, null);
    if (cursor.moveToFirst())   {

        registrationID = cursor.getString(INDEX_CUST_REGID);
    }

SQL 创建表调用:

final String SQL_CREATE_CUSTOMER_TABLE = "CREATE TABLE " + CustomerEntry.TABLE_NAME + " (" +
            CustomerEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
            CustomerEntry.COLUMN_CUST_NAME + " TEXT NOT NULL, " +
            CustomerEntry.COLUMN_CUST_EMAIL + " TEXT NOT NULL, " +
            CustomerEntry.COLUMN_CUST_QRHASH + " TEXT NOT NULL," +
            CustomerEntry.COLUMN_CUST_REGID + " TEXT NOT NULL)";

在这种情况下,INDEX_CUST_REGID 是与 String[] 投影中的位置相关的最终静态 int,在这种情况下是第三个位置。这会抛出是有道理的,但是是否有一种方法或方法可以查询 SyncAdapter 以获取特定列,例如 CUST_REGID,或者在尝试使用 cursor.getString() 之前检查请求的列是否已返回?

这也可能解决我在知道 EMAIL、NAME、QRHASH 之前保存 Reg ID 时遇到的另一个问题。不能只插入一列而其余列也没有值(非空),即使它将是毫无价值的数据并尽快被覆盖。

方法尝试存储 Reg ID。

private void storeRegistrationID(Context context, String regID) {
    //DB insert regid
    ContentValues cValues = new ContentValues();
    cValues.put(CustomerEntry.COLUMN_CUST_NAME, "");
    cValues.put(CustomerEntry.COLUMN_CUST_EMAIL, "");
    cValues.put(CustomerEntry.COLUMN_CUST_QRHASH, "");
    cValues.put(CustomerEntry.COLUMN_CUST_REGID, regID);
    mContext.getContentResolver().insert(CustomerEntry.CONTENT_URI, cValues);
}

按要求投影:

 String[] CUSTOMER_PROJECTION = new String[]{
        CustomerEntry._ID,
        CustomerEntry.COLUMN_CUST_NAME,
        CustomerEntry.COLUMN_CUST_EMAIL,
        CustomerEntry.COLUMN_CUST_QRHASH,
        CustomerEntry.COLUMN_CUST_REGID
};

【问题讨论】:

  • 显示投影。

标签: java android sqlite


【解决方案1】:

您确定该表是实际创建的吗? SQL_CREATE_CUSTOMER_TABLE 文本字符串的末尾缺少一个分号 - 尽管我不确定是否必须运行 sql 来创建表。我建议在 Eclipse 模拟器上运行它,然后从 DDMS 的角度,在可以使用 Firefox 的 SQLite Manager 插件打开它的地方复制数据库 - 这将显示数据库表。

【讨论】:

  • 好吧,你肯定在那里发现了一个错误。我会看看我可以在 Android Studio 中使用什么调试来进行数据库。
猜你喜欢
  • 1970-01-01
  • 2010-11-10
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 2019-02-28
  • 1970-01-01
  • 2019-05-21
  • 1970-01-01
相关资源
最近更新 更多