在从中访问数据之前初始化 SQLite Cursor

Initialize SQLite Cursor before accessing data from it

我正在尝试在通过 FCM 收到通知后将数据插入 SQLite 数据库。出于调试目的,当在 HomeScreen activity.

上单击 SHow Token 时,我还在我的数据库中插入了一个虚拟数据

然而我得到

"I am getting "无法从 CursorWindow 读取第 0 行,列 -1。在从中访问数据之前,请确保 Cursor 已正确初始化。"

Link 我的代码:- GitHub

谁能检查一下我的代码,让我知道哪里出错了。

注意 - 我在下面添加了 HomeScreen.java、MyFirebaseMessagingService.java 和 NotificationDetails.java

private SQLiteDB dbHelper = new SQLiteDB(this);
由于建议
私有 SQLiteDB dbHelper;
对我没用

当我在上面使用时,我一直得到 Nullpointer 异常,所以我想因为 SQLiteDB class 构造函数正在接受一个上下文,所以让我传递一个,post 我没有得到 NullPointer异常。

现在我在没有完全意识到上下文的概念的情况下这样做了,我一直在努力思考这个概念,但是由于我是一个极端的菜鸟 android 我现在还不能掌握它.我怀疑这可能与我传递的上下文有关。

有人可以在这里帮助我提供有关如何解决此问题的详细说明,我已经通过许多其他线程解决此问题但无法解决因此在经历多个 SO 问题 5 小时后,我 post这个。

提前感谢社区中的每一个人的帮助。 :)

编辑

根据管理员的建议,我在下面包含了我的代码片段。

我调用游标的地方

   dbHelper.insertNotification("This is a notification");
                //Check if the message contains data
                Cursor rs = dbHelper.getAllNotifications();
                rs.moveToFirst();
                token_text.setText("Token: " +rs.getString((rs.getColumnIndex("NOTIFICATION_DETAILS"))));

在SQLiteDB.java

中插入通知函数
public boolean insertNotification(String notification){
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();
    contentValues.put(NOTIFICATION_DETAILS,notification);
    db.insert(NOTIFICATION_TABLE_NAME,null,contentValues);
    return true;
}  

getAllNotifications 函数

public Cursor getAllNotifications() {
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor res =  db.rawQuery( "SELECT * FROM " + NOTIFICATION_TABLE_NAME, null );
    return res;
}

Couldn't read row 0, col -1 from CursorWindow.

表示您正在尝试从第 0 行(第一行)获取偏移量为 -1 的列。所以你提供了一个无效的偏移量(它不能是-1的偏移量,偏移量必须是0或更大并且最大值将比Cursor中的列数少1 ).

最可能的原因是 Cursor 方法 getColumnIndex(the_column_name_as_a_string) 将 return -1当在 Cursor 中找不到传递给方法的列时。请注意,由于错误,列名称区分大小写。

因此您的问题是 Cursor 不包含列名 NOTIFICATION_DETAILS 并且由于您使用了 *(所有列),因此该列不存在在 table.

看起来你应该使用字符串变量 NOTIFICATION_DETAILS 所以你可能需要使用 :-

token_text.setText("Token: " +rs.getString((rs.getColumnIndex(NOTIFICATION_DETAILS)))); //<<<<<<<<<< double quotation marks removed.

额外

您永远不要假设 moveToFirst(或任何 Cursor 移动????方法)实际上执行移动。您应该始终 检查returned 值。如果移动成功,它将是 true,否则它将是 false

  • 再次注意,传递给 getColumnIndex 方法的列名是大小写相关的。

  • 因此你应该使用像

  • 这样的东西

:-

       dbHelper.insertNotification("This is a notification");
       //Check if the message contains data
       Cursor rs = dbHelper.getAllNotifications();
       if (rs.moveToFirst()) {
           token_text.setText("Token: " +rs.getString((rs.getColumnIndex(NOTIFICATION_DETAILS))));
       } else {
           ........ code here if anything need to be done if there are no rows extracted 
       }

补充评论:-

Cursor rs = dbHelper.getAllNotifications(); rs.moveToFirst(); do{ for (int i = 0; i < rs.getColumnCount(); i++) { notification_array.add(rs.getString((rs.getColumnIndex(NOTIFICATION_DETAILS)))); } }while (rs.moveToNext());

使用下面的方法简单得多:-

Cursor rs = dbHelper.getAllNotifications();
while (rs.moveToNext()) {
    notification_array.add(rs.getString((rs.getColumnIndex(NOTIFICATION_DETAILS))));
}