由于 CursorIndexOutOfBoundsException(放入交错的字符串数组),无法检索 Cursor 的全部内容

Unable to retrieve entire contents of Cursor due to CursorIndexOutOfBoundsException (to put into jagged array of strings)

我正在尝试获取光标的内容并将它们放入二维字符串中以便稍后在我的应用程序中使用。为此,我编写了以下函数:

public String[][] cursorTo2dString (Cursor cursor) {

    int columnCount = cursor.getColumnCount();
    int count = cursor.getCount();
    String[][] string2dArray = new String[count][columnCount];
    Log.i("StringLengths", count + " & " + columnCount);
    Log.i("CursorConts", DatabaseUtils.dumpCursorToString(cursor));
    if (cursor.moveToFirst())
    {
        for (int j=0; j<count && !cursor.isAfterLast(); j++)
        {
            for (int i=0; i<columnCount; i++)
            {
                Log.i("Cursor", cursor.getString(i));
                string2dArray[j][i] = cursor.getString(i);
                Log.i("StringPoint", string2dArray[j][i]);
            }
            cursor.moveToNext();
        }
    }

    return string2dArray;
}

当程序崩溃时,控制台会显示以下结果

I/StringLengths: 1 & 2
I/CursorConts: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@f7e2e6f
               0 {
                  TagIdNo=3866
                  TagName=No Parental Permission
               }
               <<<<<
I/Cursor: 3866
I/StringPoint: 3866
I/Cursor: No Parental Permission
I/StringPoint: No Parental Permission
I/MovePos: true & false
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.programming.workingpomproject, PID: 29771
                  java.lang.IllegalStateException: Could not execute method for android:onClick
                      at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
                      at android.view.View.performClick(View.java:5226)
                      at android.view.View$PerformClick.run(View.java:21266)
                      at android.os.Handler.handleCallback(Handler.java:739)
                      at android.os.Handler.dispatchMessage(Handler.java:95)
                      at android.os.Looper.loop(Looper.java:168)
                      at android.app.ActivityThread.main(ActivityThread.java:5845)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
                   Caused by: java.lang.reflect.InvocationTargetException
                      at java.lang.reflect.Method.invoke(Native Method)
                      at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
                      at android.view.View.performClick(View.java:5226) 
                      at android.view.View$PerformClick.run(View.java:21266) 
                      at android.os.Handler.handleCallback(Handler.java:739) 
                      at android.os.Handler.dispatchMessage(Handler.java:95) 
                      at android.os.Looper.loop(Looper.java:168) 
                      at android.app.ActivityThread.main(ActivityThread.java:5845) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) 
                   Caused by: android.database.CursorIndexOutOfBoundsException: Index 1 requested, with a size of 1
                      at android.database.AbstractCursor.checkPosition(AbstractCursor.java:460)
                      at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
                      at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
                      at com.example.programming.workingpomproject.DbHelper.cursorTo2dString(DbHelper.java:155)
                      at com.example.programming.workingpomproject.DbHelper.select(DbHelper.java:89)
                      at com.example.programming.workingpomproject.DbHelper.select(DbHelper.java:92)
                      at com.example.programming.workingpomproject.MainActivity.testDbMethodGet(MainActivity.java:66)
                      at com.example.programming.workingpomproject.MainActivity.dbStuff(MainActivity.java:61)
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
                      at android.view.View.performClick(View.java:5226) 
                      at android.view.View$PerformClick.run(View.java:21266) 
                      at android.os.Handler.handleCallback(Handler.java:739) 
                      at android.os.Handler.dispatchMessage(Handler.java:95) 
                      at android.os.Looper.loop(Looper.java:168) 
                      at android.app.ActivityThread.main(ActivityThread.java:5845) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) 

任何关于如何解决这个问题的建议,以及对我的方法的任何修改,将不胜感激。

感谢您的所有帮助!对于我的编码标准出现的任何问题,我深表歉意,这是我的第一个 android 应用程序,也是我第一次使用 Java,尽管我以前用 C# 编写过。

编辑1:

迄今为止的异常出现在行

if (cursor.moveToFirst()) //line 117

或者至少这是 Android Studio 调试器突出显示的行。我怀疑这里实际上并没有发生异常,因为该行号是 117 并且 if 语句在第 129 行结束,它们都没有实际出现在调试器中;此外,程序流程直接从

行跳转到此处
Log.i("Cursor", cursor.getString(i)); //line 123

一旦 i 等于 2 而 j 等于 0。事实表明,我留在以下两行的断点在内部循环的这次迭代中没有被触发。

我修改了上面的代码部分以显示当前情况。这些修改包括删除之前存在的最后两个 Log.i 语句。这些如下

Log.i("MovePos", String.valueOf(cursor.isAfterLast()) + " & " + cursor.moveToPosition(cursor.getColumnIndex("TagName")));
    Log.i("LOOK HERE", cursor.getString(0));

根据控制台日志,无论如何都没有 运行。

以下适合我。

public String[][] makeArrayFromCursor(Cursor csr) {

       String[][] rv = new String[csr.getCount()][csr.getColumnCount()];
       if (csr.getCount() > 0) {
           int called_pos = csr.getPosition();
           csr.moveToPosition(-1);
           while (csr.moveToNext()) {
               for (int i=0; i < csr.getColumnCount(); i++) {
                   rv[csr.getPosition()][i] = csr.getString(i);
               }
           }
           csr.moveToPosition(called_pos);
       }

       return rv;
   }

注释

  • 如果光标为空,将 return 空字符串数组。
  • 将通过 called_pos.
  • 将光标重新定位到它的原始位置
  • 移动到 -1 是在第一行之前(再次以防万一使用了游标并将其定位在其他地方)。