Android Studio SQLite,索引游标越界异常

Android Studio SQLite, Index Cursor Out Of Bounds Exception

我正在尝试开发一个应用程序,该应用程序将数据本地存储在 SQLite 数据库中,稍后当平板电脑 运行 该应用程序具有 WiFi 连接时,这些数据可以传输到在线数据库。本地存储工作正常 - 每次我添加记录时,它都会毫无问题地存储。与在线数据库的连接没有问题——如果我向它发送空白数据,它会输入一条空白记录。但是,当我尝试从 SQLite 获取数据并发送该数据时,出现索引游标越界异常,我不明白为什么。

我的Java代码如下:

public void send_onClick(View v) {
    int numRecords = data.getCount();
    final TextView records = (TextView) findViewById(R.id.lblRecords);
    final Button send = (Button) findViewById(R.id.btnSend);

    send.setClickable(false);
    // Loop through the records and send them
    while (data.moveToNext()) {

        // Load the string request
        StringRequest stringRequest = new StringRequest(Request.Method.POST, serverUrl,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        if (!response.equals("false")) success = true;
                        else Toast.makeText(SendDataActivity.this, "False response.", Toast.LENGTH_SHORT).show();
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(SendDataActivity.this, "An unknown error occurred.", Toast.LENGTH_SHORT).show();
                        error.printStackTrace();
                    }
                }){

            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();
                params.put("key","###");
                params.put("a", data.getString(1));
                params.put("b", data.getString(2));
                params.put("c", data.getString(3));
                params.put("d", data.getString(4));
                params.put("e", data.getString(5));
                params.put("f", data.getString(6));
                params.put("g", data.getString(7));
                params.put("h", data.getString(8));
                params.put("i", data.getString(9));
                params.put("j", data.getString(10));
                return params;
            }
        };

        RequestHandler.getInstance(SendDataActivity.this).addToRequestQueue(stringRequest);

        // Remove the record from the SQLite if it worked
        if (success) {
            dbHelper.deleteRecord(data.getString(0));
            numRecords--;
            records.setText(Integer.toString(numRecords));
            success = false;
        }

    }

    send.setClickable(true);

    // If there are no records left, hide the button
    if (numRecords == 0) send.setVisibility(View.GONE);
}

所以正如你所看到的,当用户点击"send"时,它应该循环遍历SQLite中的每条记录并发送一个HTTP POST请求。我知道 post 请求有效,因为如果您用空格替换参数,它就会被添加到数据库中。问题似乎出在 data.getString(1) 等我试图放入地图中。

E/Volley: [181] NetworkDispatcher.processRequest: Unhandled exception android.database.CursorIndexOutOfBoundsException: Index 1 requested, with a size of 1
      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.lensofamoose.testapp.SendDataActivity$override.getParams(SendDataActivity.java:118)
          at com.lensofamoose.testapp.SendDataActivity$override.access$dispatch(SendDataActivity.java)
          at com.lensofamoose.testapp.SendDataActivity.getParams(SendDataActivity.java:0)
          at com.android.volley.Request.getBody(Request.java:464)
          at com.android.volley.toolbox.HurlStack.addBodyIfExists(HurlStack.java:275)
          at com.android.volley.toolbox.HurlStack.setConnectionParametersForRequest(HurlStack.java:249)
          at com.android.volley.toolbox.HurlStack.executeRequest(HurlStack.java:94)
          at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:123)
          at com.android.volley.NetworkDispatcher.processRequest(NetworkDispatcher.java:131)
          at com.android.volley.NetworkDispatcher.processRequest(NetworkDispatcher.java:111)
          at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:90)

你可以在这里看到我得到的错误告诉我我有一个游标越界异常。如果只有一个记录,那么它是索引 1,大小 1。如果有两个记录,那么我得到索引 2,大小 2,等等。"SendDataActivity.java:118" 是我尝试使用 [=35= 的第一行]().

我已经尝试了所有我能想到的循环方法。我试过将 moveToFirst() 放在 do-while 之后。我试过检查 isAfterLast() 并返回是否为真。似乎没有什么能解决问题——我看不出它试图获取越界索引的逻辑原因,因为即使我更改循环以尝试将其考虑在内,我似乎仍然会遇到同样的错误。有什么想法吗?

编辑:

数据提取如下:

public Cursor getData() {
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor data = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
    return data;
}

并且此方法通过以下内容传递到数据变量中:

data = dbHelper.getData();

玩了几个小时后,我发现我试图访问数据的范围是问题所在。如果在 while 循环开始时,我将必要的数据存储在最终变量中,并从 params.map() 而不是 data.getString() 中调用这些数据,我不会收到任何错误。所以相反,我得到这个:

while (data.moveToNext()) {

final String a = data.getString(1);
            final String b = data.getString(2);
            final String c = data.getString(3);
            final String d = data.getString(4);
            final String e = data.getString(5);
            final String f = data.getString(6);
            final String g = data.getString(7);
            final String h = data.getString(8);
            final String i = data.getString(9);
            final String j = data.getString(10);

    // Load the string request
    StringRequest stringRequest = new StringRequest(Request.Method.POST, serverUrl,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    if (!response.equals("false")) success = true;
                    else Toast.makeText(SendDataActivity.this, "False response.", Toast.LENGTH_SHORT).show();
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Toast.makeText(SendDataActivity.this, "An unknown error occurred.", Toast.LENGTH_SHORT).show();
                    error.printStackTrace();
                }
            }){

        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();
            params.put("key","###");
            params.put("a", a);
            params.put("b", b);
            params.put("c", c);
            params.put("d", d);
            params.put("e", e);
            params.put("f", f);
            params.put("g", g);
            params.put("h", h);
            params.put("i", i);
            params.put("j", j);
            return params;
        }
    };

    RequestHandler.getInstance(SendDataActivity.this).addToRequestQueue(stringRequest);

    // Remove the record from the SQLite if it worked
    if (success) {
        dbHelper.deleteRecord(data.getString(0));
        numRecords--;
        records.setText(Integer.toString(numRecords));
        success = false;
    }

}