【问题标题】:How can I reference cursor item in a for loop or while loop?如何在 for 循环或 while 循环中引用光标项?
【发布时间】:2022-03-17 21:41:42
【问题描述】:

我正在尝试遍历创建选项卡的数据库值。我设置了一个名为 createTab 的方法,它接受一个 Long 值和一个 String 值。它正在处理静态数据,但我很难理解如何遍历 SQLite 数据库记录。

这是我失败的尝试(将 [lessthan] 替换为小于符号):

for (int i = 0; i [lessthan] mCursor.getCount(); i++)
{
 createTab(
  mCursor.getLong(mCursor.getColumnIndexOrThrow("_id")),
  mCursor.getString(mCursor.getColumnIndexOrThrow("category")));
}

您可能不需要 LogCat 来知道我在上面的代码中做错了什么,但以防万一......

08-27 21:28:18.268: ERROR/AndroidRuntime(232): Caused by: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 3
08-27 21:28:18.268: ERROR/AndroidRuntime(232):     at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
08-27 21:28:18.268: ERROR/AndroidRuntime(232):     at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:172)
08-27 21:28:18.268: ERROR/AndroidRuntime(232):     at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:99)
08-27 21:28:18.268: ERROR/AndroidRuntime(232):     at com.toBuy.Main.createTabs(Main.java:51)
08-27 21:28:18.268: ERROR/AndroidRuntime(232):     at com.toBuy.Main.onCreate(Main.java:38)
08-27 21:28:18.268: ERROR/AndroidRuntime(232):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
08-27 21:28:18.268: ERROR/AndroidRuntime(232):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
08-27 21:28:18.268: ERROR/AndroidRuntime(232):     ... 11 more
08-27 21:28:18.278: INFO/Process(54): Sending signal. PID: 232 SIG: 3
08-27 21:28:18.278: INFO/dalvikvm(232): threadid=7: reacting to signal 3
08-27 21:28:18.338: INFO/dalvikvm(232): Wrote stack trace to '/data/anr/traces.txt'
08-27 21:28:18.508: INFO/ARMAssembler(54): generated scanline__00000077:03515104_00000000_00000000 [ 27 ipp] (41 ins) at [0x285a68:0x285b0c] in 713498 ns
08-27 21:28:18.518: INFO/ARMAssembler(54): generated scanline__00000077:03515104_00001001_00000000 [ 64 ipp] (84 ins) at [0x285b10:0x285c60] in 1897448 ns
08-27 21:28:28.086: WARN/ActivityManager(54): Launch timeout has expired, giving up wake lock!
08-27 21:28:28.097: WARN/ActivityManager(54): Activity idle timeout for HistoryRecord{4390bf70 com.toBuy/.Main}

感谢您的帮助。

【问题讨论】:

    标签: android android-cursor


    【解决方案1】:

    您需要先定位光标,然后才能调用getLonggetString。发出查询后,Cursor 位于第一行之前,因此您应该在循环中调用 moveToNext。比如:

    int size = mCursor.getCount();
    for (int i = 0; i < size; i++) {
    
        // Position the cursor
        mCursor.moveToNext();
    
        // Fetch your data values
        long id = mCursor.getLong(mCursor.getColumnIndex("_id"));
        String cat = mCursor.getString(mCursor.getColumnIndex("category"));
    }
    

    【讨论】:

    • 感谢您的回复。我在这一点上挣扎的是引用光标内的列。 // Fetch your data values 如何查找 Long 列 (_id) 和 String 列 (category)?
    • 您仍然可以像在示例中一样访问列值。 Cursor 对象包含一个指向它当前指向的数据库中的行的指针,并且您的示例代码只需要在调用任何 get* 方法之前定位它。如果这不能解决您的问题,我会将数据库从设备(或模拟器)中取出并仔细检查架构。
    【解决方案2】:

    在我的代码中,我从 SQLite 数据库中获取值,并使用 Cursor 将该值存储在模型类的对象数组中(FriendData 是我的模型类)。

       Cursor cursor = friendAdapter.fetchData(); //call method for fetch data from databse and fetched data is stored into cursor
        int cursorSize = cursor.getCount();
    
        if (cursor != null && cursor.moveToFirst()) {
             FriendData[] friendData=new FriendData[cursorSize];  //create array of objects as size of cursor
    
                for (int i = 0; i < cursorSize; i++) {
                       friendData[i]=new FriendData();
    
                      /*store fetched data in some variables. In my code I have store value of cursor in friendName String variable*/
                      friendName = cursor.getString(cursor.getColumnIndex(FriendAdapter.FRIEND_NM));
    
                     /* set friendName variable value in array of object*/
                     friendData[i].setFriendName(friendName);
    
                  cursor.moveToNext();  //move cursor for pointing to next fetched record
               }
         }
    

    首先,我检查光标的条件是否为空,然后移动光标对象以指向获取的第一条记录。然后我使用 getCount() 方法计算光标的大小。之后,for循环用于将所有数据存储在对象数组中,最后光标指向获取的下一条记录。

    【讨论】:

      【解决方案3】:

      使用以下 for 循环:

         for(mCursor.moveToFirst();!mCursor.isAfterLast();mCursor.moveToNext()){
              createTab(
        mCursor.getLong(mCursor.getColumnIndexOrThrow("_id")),
        mCursor.getString(mCursor.getColumnIndexOrThrow("category")));    
              }
      

      虽然,while 循环会简单得多:

      while (mCursor.moveToNext()) { createTab(
        mCursor.getLong(mCursor.getColumnIndexOrThrow("_id")),
        mCursor.getString(mCursor.getColumnIndexOrThrow("category")));    
      

      }

      在这两种情况下,您都不需要手动设置光标的起始位置。

      【讨论】:

        猜你喜欢
        • 2021-07-27
        • 1970-01-01
        • 1970-01-01
        • 2014-08-21
        • 2013-07-21
        • 1970-01-01
        • 1970-01-01
        • 2020-03-01
        • 2014-02-15
        相关资源
        最近更新 更多