【问题标题】:Couldn't read row 0, col 2 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it无法从 CursorWindow 读取第 0 行第 2 列。确保在从光标访问数据之前正确初始化光标
【发布时间】:2019-06-10 07:00:08
【问题描述】:

在我的应用程序中,我有一个表单。哪个用户将 CNIC 放在首位。如果他的 CNIC 已经存在于 SQLite 数据库中。用户名和手机号码将自动填写在编辑文本中(使用 TextWatcher)。但是每当我键入相同的 CNIC 时,应用程序就会崩溃。如果 CNIC 存在于数据库中,而不是自动填写姓名和电话字段,应用程序将崩溃。我已经尝试了很多,但无法解决我的问题。

查询方法:

public List<SGenerateModel> getGeneratedData(String seller_cnic){
    SQLiteDatabase db = this.getWritableDatabase();
    String query = "SELECT " + TABLE_COL2 + ", " + TABLE_COL3 + " FROM " + TABLE_NAME + " WHERE " + TABLE_COL4 + " =?" ;
    Cursor cursor = db.rawQuery(query, new String[]{"" + seller_cnic});

    List<SGenerateModel> listOfSGModel = new ArrayList<>();
    while(cursor.moveToNext()){
        SGenerateModel sGenerateModel = new SGenerateModel(cursor.getString(1), cursor.getString(2));
        sGenerateModel.setId(cursor.getInt(cursor.getColumnIndex(DatabaseHelper.TABLE_COL1)));
        listOfSGModel.add(sGenerateModel);
    }
    return listOfSGModel;
}

调用的查询方法:

   public void generate(){

    if (etSname != null)
        selName = (!etSname.getText().toString().equals("")?
                etSname.getText().toString() : "NULL");

    if (etSphone != null)
        selPhone = (!etSphone.getText().toString().equals("")?
                etSphone.getText().toString() : "NULL");

    if (etScnic != null)
        selCnic = (!etScnic.getText().toString().equals("")?
                etScnic.getText().toString() : "NULL");

    sGenerateModelList = databaseHelper.getGeneratedData(selCnic);
    for (SGenerateModel sGenerateModel : sGenerateModelList){
        selName = sGenerateModel.getSellerName() ;
        etSname.setText(selName);
        selPhone = sGenerateModel.getSellerMobile();
        etSphone.setText(selPhone);
    }
}

TextWatcher 代码:

TextWatcher textWatcher2 = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            generate();
        }
    };

etSname.addTextChangedListener(textWatcher2);
    etSphone.addTextChangedListener(textWatcher2);
    etScnic.addTextChangedListener(textWatcher2);

LogCat 错误:

 java.lang.IllegalStateException: Couldn't read row 0, col 2 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
    at android.database.CursorWindow.nativeGetString(Native Method)
    at android.database.CursorWindow.getString(CursorWindow.java:438)
    at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
    at com.example.cattleapp.helpers.DatabaseHelper.getGeneratedData(DatabaseHelper.java:218)
    at com.example.cattleapp.activities.MainActivity.generate(MainActivity.java:536)
    at com.example.cattleapp.activities.MainActivity$7.afterTextChanged(MainActivity.java:241)
    at android.widget.TextView.sendAfterTextChanged(TextView.java:9485)
    at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:12080)
    at android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:1262)
    at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:574)
    at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:507)
    at com.santalu.maskedittext.MaskTextWatcher.format(MaskTextWatcher.kt:67)
    at com.santalu.maskedittext.MaskTextWatcher.afterTextChanged(MaskTextWatcher.kt:21)
    at android.widget.TextView.sendAfterTextChanged(TextView.java:9485)

【问题讨论】:

    标签: android android-sqlite android-textwatcher


    【解决方案1】:
    String query = "SELECT " + TABLE_COL2 + ", " + TABLE_COL3 + " FROM " + TABLE_NAME + " WHERE " + TABLE_COL4 + " =?" ;
    

    在这一行中,您仅获取 2 列(索引 0 和 1),但在获取时您正在尝试获取第 2 列。即

    cursor.getString(2)
    

    您只能获取第 0 列和第 1 列。

    试试这个:

    SGenerateModel sGenerateModel = new SGenerateModel(cursor.getString(0), cursor.getString(1));
    

    编辑:

    使用后请务必关闭光标。在您的代码中,在 while 循环之后将此行放在方法 return listOfSGModel 之前的 getGeneratedData

    cursor.close();
    

    【讨论】:

    • 应用程序仍然崩溃,但现在 logcat 错误是:android.database.CursorWindowAllocationException:2048 kb 的光标窗口分配失败。 # Open Cursors=939 (# cursors opens by this proc=939)… etSname.setText(selName);在 generate() 方法的这一行上。
    • @UsamaSajid 那么您将非常大的字符串存储在数据库中。调试从游标获得的值并验证它。
    • 我已经调试过了,五个字母的名字和电话号码是 12 位数字。我不认为它是一个大字符串
    • 不,先生!应用程序仍然崩溃。我认为生成方法有问题。
    猜你喜欢
    • 2020-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多