无法读取光标窗口android的行

Posted

技术标签:

【中文标题】无法读取光标窗口android的行【英文标题】:failed to read row of cursor window android 【发布时间】:2016-01-24 11:47:53 【问题描述】:

我在我的 android 应用程序中使用 sqlite 来处理我的会话。我希望用户注册,然后登录后转到配置文件并在配置文件中显示一些数据库项目。 android studio 一直显示这个:Unable to start activity ComponentInfocom.example.neshat.bluedot/com.example.neshat.bluedot.profile: java.lang.IllegalStateException: Couldn't read row 0, col 5 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.

我检查了类似的问题,但没有一个是我的答案。我为你复制了相关代码。 这是我的 sqlitehandlre:

@Override
public void onCreate(SQLiteDatabase db)

    String CREATE_LOGIN_TABLE = "CREATE TABLE " + TABLE_USER + "("
            + KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
            + KEY_EMAIL + " TEXT UNIQUE," + KEY_TOTALPOINTS + "TEXT," + KEY_DIGIPOINTS + "TEXT,"  + KEY_UID + " TEXT,"
            + KEY_CREATED_AT + " TEXT" + ");";
    db.execSQL(CREATE_LOGIN_TABLE);

    Log.d(TAG, "Database tables created");


// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    // Drop older table if existed
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_USER);

    // Create tables again
    onCreate(db);


/**
 * Storing user details in database
 * */                  //      db.addUser(name, email,totalpoints, digipoints, uid, created_at);

public void addUser(String name, String email ,String totalpoints, String digipoints , String uid, String created_at) 
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(KEY_NAME, name); // Name
    values.put(KEY_EMAIL, email); // Email
    values.put(KEY_TOTALPOINTS, totalpoints);
    values.put(KEY_DIGIPOINTS, digipoints);
    values.put(KEY_UID, uid);
    values.put(KEY_CREATED_AT, created_at); // Created At

    // Inserting Row
    long id = db.insert(TABLE_USER, null, values);
    db.close(); // Closing database connection

    Log.d(TAG, "New user inserted into sqlite: " + id);


/**
 * Getting user data from database
 * */
public HashMap<String, String> getUserDetails() 
    HashMap<String, String> user = new HashMap<String, String>();
    String selectQuery = "SELECT  * FROM " + TABLE_USER;

    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);
    // Move to first row
    cursor.moveToFirst();
    if (cursor.getCount() > 0) 
        user.put("name", cursor.getString(1));
        user.put("email", cursor.getString(2));
        user.put("totalpoints", cursor.getString(3));
        user.put("digipoints", cursor.getString(4));
        user.put("uid", cursor.getString(5));
        user.put("created_at", cursor.getString(6));
    
    cursor.close();
    db.close();
    // return user
    Log.d(TAG, "Fetching user from Sqlite: " + user.toString());

    return user;

这是我的注册活动

private void registerUser(final String name, final String email, final String password)

    // Tag used to cancel the request
    String tag_string_req = "req_register";

    pDialog.setMessage("Registering ...");
    showDialog();

    StringRequest strReq = new StringRequest(Method.POST, AppConfig.URL_REGISTER, new Response.Listener<String>() 

        @Override
        public void onResponse(String response) 
            Log.d(TAG, "Register Response: " + response.toString());
               Toast.makeText(getApplicationContext(), response.toString(), Toast.LENGTH_LONG).show();

            hideDialog();

            try 
                JSONObject jObj = new JSONObject(response);
                boolean error = jObj.getBoolean("error");
                if (!error)
                
                    // User successfully stored in mysql
                    // Now store the user in sqlite
                    String uid = jObj.getString("uid");

                    JSONObject user = jObj.getJSONObject("user");
                    String name = user.getString("name");
                    String email = user.getString("email");
                    String totalpoints = user.getString("totalpoints");
                    String digipoints = user.getString("digipoints");
                    String created_at = user.getString("created_at");

                    Log.d("sqlite", uid);
                    Log.d("sqlite", name);
                    Log.d("sqlite", email);
                    Log.d("sqlite", totalpoints);
                    Log.d("sqlite", digipoints);
                    Log.d("sqlite", created_at);

                    // Inserting row in users table
                    db.addUser(name, email,totalpoints, digipoints, uid, created_at);

                    Toast.makeText(getApplicationContext(), "User successfully registered. Try login now!", Toast.LENGTH_LONG).show();

                    // Launch login activity
                    Intent intent = new Intent(
                            RegisterActivity.this,
                            LoginActivity.class);
                    startActivity(intent);
                    finish();
                 else
                

                    // Error occurred in registration. Get the error
                    // message
                    String errorMsg = jObj.getString("error_msg");
                    Toast.makeText(getApplicationContext(), errorMsg, Toast.LENGTH_LONG).show();
                    Log.d("Debug", errorMsg);

                
             catch (JSONException e) 
                e.printStackTrace();
            

        
    , new Response.ErrorListener() 

        @Override
        public void onErrorResponse(VolleyError error) 
            Log.e(TAG, "Registration Error: " + error.toString());
            Toast.makeText(getApplicationContext(),
                    error.getMessage(), Toast.LENGTH_LONG).show();
            hideDialog();
        

这是我的个人资料活动:

 db = new SQLiteHandler(getApplicationContext());

    // session manager
    session = new SessionManager(getApplicationContext());
    txtName = (TextView) findViewById(R.id.name);
    pointsview = (TextView) findViewById(R.id.points);

    //txtEmail = (TextView) findViewById(R.id.email);
    btnLogout = (Button) findViewById(R.id.lgot);
    if (!session.isLoggedIn())
    
        logoutUser();
    

    //Fetching user details from sqlite
    HashMap<String, String> user = db.getUserDetails();

    String name = user.get("name");
    String email = user.get("email");
    String tpoints = user.get("totalpoints");
    String dpoints = user.get("digipoints");

    // Displaying the user details on the screen
    txtName.setText(name);
    pointsview.setText(tpoints);

这是我的日志:

  mple.neshat.bluedot E/CursorWindow﹕ Failed to read row 0, column 5 from a CursorWindow which has 2 rows, 5 columns.
01-24 05:59:22.362  11101-11101/com.example.neshat.bluedot D/AndroidRuntime﹕ Shutting down VM
01-24 05:59:22.362  11101-11101/com.example.neshat.bluedot E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.neshat.bluedot, PID: 11101
    java.lang.RuntimeException: Unable to start activity ComponentInfocom.example.neshat.bluedot/com.example.neshat.bluedot.profile: java.lang.IllegalStateException: Couldn't read row 0, col 5 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
     Caused by: java.lang.IllegalStateException: Couldn't read row 0, col 5 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.neshat.bluedot.helper.SQLiteHandler.getUserDetails(SQLiteHandler.java:101)
            at com.example.neshat.bluedot.profile.onCreate(profile.java:130)
            at android.app.Activity.performCreate(Activity.java:5933)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
            at android.app.ActivityThread.access$800(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5221)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

编辑: 我替换了 user.put("name", cursor.getString(1)); with user.put("name", cursor.getString(cursor.getColumnIndex("name")))

但我的错误已更改为:

Couldn't read row 0, col -1 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.neshat.bluedot.helper.SQLiteHandler.getUserDetails(SQLiteHandler.java:100)
        at com.example.neshat.bluedot.profile.onCreate(profile.java:130)

totalpoints 列有错误,我不明白为什么。

【问题讨论】:

【参考方案1】:

SELECT * 结果集中没有第 5 列。

看起来您已向 CREATE TABLE 添加了列,但您忘记增加数据库版本以升级它,或卸载您的应用程序以摆脱旧数据库。有关更多信息,请参阅When is SQLiteOpenHelper onCreate() / onUpgrade() run?。

请注意,您的CREATE TABLE 中还有几个空格问题:列名和类型之间缺少空格。在再次运行代码之前修复这些问题,以免出现“没有这样的列”错误,例如插入。

【讨论】:

【参考方案2】:

尝试从 Cursor 中使用此方法,而不是直接传递索引:

/**
 * Returns the zero-based index for the given column name, or -1 if the column doesn't exist.
 * If you expect the column to exist use @link #getColumnIndexOrThrow(String) instead, which
 * will make the error more clear.
 *
 * @param columnName the name of the target column.
 * @return the zero-based column index for the given column name, or -1 if
 * the column name does not exist.
 * @see #getColumnIndexOrThrow(String)
 */
int getColumnIndex(String columnName);

然后你会得到这样的东西:

user.put("email", cursor.getString(cursor.getColumnIndex("email")));

它可能会解决您的问题。

祝你好运。

【讨论】:

你的意思是例如而不是 user.put("email", cursor.getString(1));我应该使用 cursor.getColumnIndex("email");? 你应该使用 user.put("email", cursor.getString(cursor.getColumnIndex("email")));

以上是关于无法读取光标窗口android的行的主要内容,如果未能解决你的问题,请参考以下文章

如何使回车键将光标移动到 Android Studio 中的行尾,就像在 Eclipse 中一样

android.database.CursorWindowAllocationException:即使在关闭光标后,2048 kb 的光标窗口分配也失败

SQLite Android 数据库光标窗口分配 2048 kb 失败

错误:无法从 CursorWindow 读取第 0 行 col -1。确保在访问数据之前正确初始化光标

Android studio快捷键

解决Android Studio有时打开的项目,无法显示问题