【问题标题】:Android Studio SQLite, Index Cursor Out Of Bounds ExceptionAndroid Studio SQLite,索引游标越界异常
【发布时间】:2019-03-08 14:15:39
【问题描述】:

我正在尝试开发一个应用程序,它将数据本地存储在 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);
}

如您所见,当用户单击“发送”时,它应该循环遍历 SQLite 中的每条记录并发送 HTTP 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$4$override.getParams(SendDataActivity.java:118)
          at com.lensofamoose.testapp.SendDataActivity$4$override.access$dispatch(SendDataActivity.java)
          at com.lensofamoose.testapp.SendDataActivity$4.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)

您可以在此处看到我得到的错误是告诉我有一个 Cursor out of bounds 异常。如果只有一条记录,那么它是索引 1,大小 1。如果有两条记录,那么我得到索引 2,大小 2,等等。“SendDataActivity.java:118”是我尝试使用数据的第一行。获取字符串()。

我已经尝试了所有我能想到的循环方法。我试过把 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();

【问题讨论】:

  • 您能否添加创建(提取)称为数据的游标的代码。
  • 已经放在最后了。我知道数据在那里,因为 data.getCount() 返回正确的记录数,所以我不明白为什么我不能循环遍历它。

标签: android sqlite http-post android-volley android-cursor


【解决方案1】:

玩了几个小时后,我发现我试图访问数据的范围是问题所在。如果在 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;
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-08
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多