【问题标题】:Make sure the Cursor is initialized correctly before accessing data from it确保在从光标访问数据之前正确初始化光标
【发布时间】:2013-11-27 10:44:39
【问题描述】:

我正在尝试从我的数据库中获取数据。

这是我的代码:

String[] columns = new String[] {COLUMN_FACEBOOK_ALBUM_COVER, COLUMN_FACEBOOK_ALBUM_IS_ACTIVE};

        String whereClause = COLUMN_FACEBOOK_ALBUM_IS_ACTIVE + "= '" + 1 + "'";

        Cursor cAlbum = ourDatabase.query(TABLE_FACEBOOK, columns, whereClause,null, null, null, null);

        columns = new String[] {COLUMN_FACEBOOK_BIG_IMAGE, COLUMN_FACEBOOK_IMAGE_IS_ACTIVE};

        whereClause = COLUMN_FACEBOOK_IMAGE_IS_ACTIVE + "= '" + 1 + "'";

        Cursor cImage = ourDatabase.query(TABLE_FACEBOOK_IMAGES, columns, null,null, null, null, null);

        String[] list = new String[cAlbum.getCount()+cImage.getCount()];

        int p = 0;

        if(cAlbum.getCount() < 1 && cImage.getCount() < 1)
        {
            cAlbum.close();
            cImage.close();
            return null;
        }

        Log.i("cImage length", cImage.getCount()+"");
        Log.i("cAlbum length", cAlbum.getCount()+"");

        Log.i("list length", list.length+"");

        int i = cImage.getColumnIndex(COLUMN_FACEBOOK_BIG_IMAGE);
        int j = cAlbum.getColumnIndex(COLUMN_FACEBOOK_ALBUM_COVER);

        for (cAlbum.moveToFirst(); !cAlbum.isAfterLast(); cAlbum.moveToNext())
        {
            list[p] = cAlbum.getString(j);
            p++;
        }

        for (cImage.moveToFirst(); !cImage.isAfterLast(); cImage.moveToNext())
        {
            list[p] = cImage.getString(i);
            Log.i("image length", list[p].length()+"");
            p++;
        }

        cAlbum.close();
        cImage.close();

        return list;

代码在这一行失败:

list[p] = cImage.getString(i);

错误信息是:

11-27 12:34:59.683: E/CursorWindow(6901): Failed to read row 2, column 0 from a CursorWindow which has 2 rows, 2 columns.
11-27 12:34:59.683: D/AndroidRuntime(6901): Shutting down VM
11-27 12:34:59.683: W/dalvikvm(6901): threadid=1: thread exiting with uncaught exception (group=0x41e9b930)
11-27 12:34:59.693: E/AndroidRuntime(6901): FATAL EXCEPTION: main
11-27 12:34:59.693: E/AndroidRuntime(6901): java.lang.RuntimeException: Unable to create service com.example.imageswidget.WidgetService: java.lang.IllegalStateException: Couldn't read row 2, col 0 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
11-27 12:34:59.693: E/AndroidRuntime(6901):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2667)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at android.app.ActivityThread.access$1600(ActivityThread.java:153)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1329)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at android.os.Looper.loop(Looper.java:137)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at android.app.ActivityThread.main(ActivityThread.java:5227)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at java.lang.reflect.Method.invokeNative(Native Method)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at java.lang.reflect.Method.invoke(Method.java:511)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at dalvik.system.NativeStart.main(Native Method)
11-27 12:34:59.693: E/AndroidRuntime(6901): Caused by: java.lang.IllegalStateException: Couldn't read row 2, col 0 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
11-27 12:34:59.693: E/AndroidRuntime(6901):     at android.database.CursorWindow.nativeGetString(Native Method)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at android.database.CursorWindow.getString(CursorWindow.java:434)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at com.example.imageswidget.DataBaseMain.getFacebookImagesForWidget(DataBaseMain.java:943)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at com.example.imageswidget.WidgetService.onCreate(WidgetService.java:51)
11-27 12:34:59.693: E/AndroidRuntime(6901):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2657)
11-27 12:34:59.693: E/AndroidRuntime(6901):     ... 10 more

通话记录

Log.i("image length", list[p].length()+"");

在代码中断之前我接到几个电话。 问题似乎只发生在某些行上,但错误代码并没有告诉我问题是什么。

感谢您的帮助。

【问题讨论】:

    标签: android android-sqlite


    【解决方案1】:

    在我的情况下,这是因为我没有在传递给 CursorLoader 构造函数的投影中包含该列。这意味着我试图从返回的游标中不存在的列中访问数据。

    我希望这对某人有所帮助...

    【讨论】:

      【解决方案2】:

      我之前也遇到过同样的异常。在我的情况下,原因是一个包含太多数据(一个巨大的字符串)的数据库单元。从代码(COLUMN_FACEBOOK_BIG_IMAGE)来看,我猜你也遇到了同样的问题。 解决方案是检查放入数据库的字符串的大小(并在需要时缩小图像)。 希望这会有所帮助!

      【讨论】:

      • 在我的情况下,这是这个错误的问题。更多细节在这里:stackoverflow.com/questions/5406429/…
      • 这确实是我的问题。当我偶然发现你的帖子时,我花了大约 0.5 小时尝试调试它。你确实为我节省了数小时的调试时间! Muchas gracias muy amigo!!
      【解决方案3】:

      也许您正在使用旧数据库。如果您更改了数据库中的某些表、字段并且您现在正在另一台设备上尝试(即您在数据库更改之前已经安装了应用程序),您应该只删除旧数据库并创建新文件。

      【讨论】:

        【解决方案4】:

        在使用光标之前尝试调用cursor.moveToFirst ()。让我知道这是否有效。

        【讨论】:

          【解决方案5】:

          您应该修复此问题以解决以下错误消息

          无法从 CursorWindow 读取第 0 行 col -1。确保光标 在从中访问数据之前已正确初始化。

          它适用于我的代码。

          1. 在读取数据之前尝试将光标定位到moveToFirst

          2. 检查是否为空-> if (c != null &amp;&amp; c.moveToFirst()) {}

          3. 检查计数-> (c != null &amp;&amp; c.getCount() &gt;0 &amp;&amp; c.moveToFirst()){}

          【讨论】:

          • 谢谢@niharika 你救了我的一天。
          【解决方案6】:

          我的答案与 Oladipo Olasemo 相似,但我遇到了 v-tables 以及我是如何解决它的。我相信这是分享我对这个错误的经验的最佳帖子,尤其是处理 FTS3 虚拟表时,至少在我的情况下是这样。关于这个有很多问题,OP 的原始问题太笼统了,所以这是我对这个问题的看法。

          由于虚拟表的一些限制,我遇到了这个错误考虑这个:

          create virtual table V1 using FTS3 (content="MyTable", content1, content2); 
          

          当我根据 content1 或 content2 搜索特定关键字时,我意识到我正在通过此查询基于虚拟表进行查询:

          select * from V1 where V1 match 'hello'
          

          由于这是我错过的虚拟表,它将根据您构建 v-table 本身的方式投影结果集。所以它只有 content1 和 content2 的列。

          我正在开发一个 android 应用程序,它从搜索结果中查询并从结果集中选择一个项目,我的后端处理处理所选项目并查询列集中不存在的信息。因此,给我这个错误。

          我解决这个问题的方法虽然不是那么出色,但它是从 v-table 中查询结果以获取每个项目的 id,它总是有的。然后我从我获得的结果 id 构造一个查询字符串库,然后使用它来检索具有我需要的投影的必要数据。我从这个question得到了一个想法

          我相信有更多方法可以遇到此错误。我花了将近一个小时来找出可能导致这种情况的原因。对我来说,日志上投射的错误不是很有帮助。如果您真正了解数据在应用中的流动方式,这真的很有帮助。

          【讨论】:

            【解决方案7】:

            初始化数据库事务中的游标。

            Cursor cAlbum = null, cImage = null;
            db.beginTransaction();
            try {
                // init cursors
                cAlbum = db.query(...);
                cImage = db.query(...);
            } catch(SQLException e) {
                e.printStackTrace();
            } finally {
                db.endTransaction();
            }
            

            检查游标是否不为空。

            if(cAlbum != null && cImage != null) {
                while(cAlbum.moveToNext()) {
                    // get data from cAlbum and do what you need
                }
                while(cImage.moveToNext()) {
                    // get data from cImage and do what you need
                }
            
                cAlbum.close();
                cImage.close();
            }
            

            【讨论】:

            • 这不是 OP 的问题:游标是非空的。
            猜你喜欢
            • 2017-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-02-27
            • 2012-05-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多