Android 数据库辅助方法调用在返回字符串时崩溃

Android database helper method call crashes when returning string

需要帮助找出我的应用程序崩溃的原因(我的应用程序没有响应消息)。

主要activity代码:

public class MainActivity extends AppCompatActivity {

Context context;

EditText etUsername, etPassword;
Button btnLogin, btnGoToRegister;

AdapterDatabase database;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    context = this;

    database = new AdapterDatabase(this);

    etUsername = (EditText) findViewById(R.id.etUsernameLogin);
    etPassword = (EditText) findViewById(R.id.etPasswordLogin);
    btnLogin = (Button) findViewById(R.id.btnLoginUser);
    btnGoToRegister = (Button) findViewById(R.id.btnGoToRegister);

    btnLogin.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String mUsername = etUsername.getText().toString();
            String mPassword = etPassword.getText().toString();
            String mPasswordDB = null;
            if((mUsername.length() > 0) && (mPassword.length() > 0)) {
                if(database.userExistDatabase(mUsername)) {
                    Message.message(context, "User " + mUsername + " exists in database.");
                    // call that causes crash
                    mPasswordDB = database.getPasswordForUser(mUsername);
                    if(mPasswordDB == null) {
                        Message.message(context, "Null string.");
                    }
                    else {
                        Message.message(context, "Password: " + mPasswordDB);
                    }
                }
            }
            else {
                String message = "";
                if(mUsername.length() == 0) {
                    message += "Username required. ";
                }
                if(mPassword.length() == 0) {
                    message += "Password required.";
                }
                Message.message(context, message);
            }
        }
    });

    btnGoToRegister.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(context, RegisterActivity.class);
            startActivity(intent);
        }
    });
}

}

数据库适配器代码:

public class AdapterDatabase {

 HelperDatabase helperDatabase;

    public AdapterDatabase(Context context) {
        helperDatabase = new HelperDatabase(context);
    }

    public long addUser(String mUsername, String mPassword, int mRole){
        long id;
        SQLiteDatabase db = helperDatabase.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(helperDatabase.USER_NAME, mUsername);
        contentValues.put(helperDatabase.USER_PASSWORD, mPassword);
        contentValues.put(helperDatabase.USER_ROLE, mRole);
        id = db.insert(helperDatabase.TABLE_1_NAME, null, contentValues);
        db.close();
        return id;
    }

    public boolean userExistDatabase(String mUsername) {
        int count;
        SQLiteDatabase db = helperDatabase.getWritableDatabase();
        String[] columns = { helperDatabase.USER_NAME };
        String condition = helperDatabase.USER_NAME + " ='" + mUsername + "'";
        Cursor cursor = db.query(helperDatabase.TABLE_1_NAME,
                columns, condition, null, null, null, null);
        count = cursor.getCount();
        db.close();
        if(count == 1) {
            return true;
        }
        else {
            return false;
        }
    }

    @Nullable
    public String getPasswordForUser(String mUsername) {
        int index;
        String mPassword;
        String[] columns = { helperDatabase.USER_NAME, helperDatabase.USER_PASSWORD };
        String condition = helperDatabase.USER_NAME + " ='" + mUsername + "'";
        SQLiteDatabase db = helperDatabase.getWritableDatabase();
        Cursor cursor = db.query(helperDatabase.TABLE_1_NAME, columns, condition,
                null, null, null, null);
        if(cursor.getCount() < 1) return null;
        index = cursor.getColumnIndex(helperDatabase.USER_PASSWORD);
        mPassword = cursor.getString(index);
        db.close();
        return mPassword;
    }

    public ArrayList<String> getAllUsers() {
        ArrayList<String> users;
        int numRows, index;
        String pUser;
        String[] columns = { helperDatabase.USER_NAME, helperDatabase.USER_PASSWORD };
        SQLiteDatabase db = helperDatabase.getWritableDatabase();
        Cursor cursor = db.query(helperDatabase.TABLE_1_NAME, columns,
                null, null, null, null, null
        );
        numRows = cursor.getCount();
        if(numRows < 1) {
            return null;
        }
        users = new ArrayList<String>(numRows);
        while (cursor.moveToNext()) {
            index = cursor.getColumnIndex(helperDatabase.USER_NAME);
            pUser = cursor.getString(index);
            pUser += " ";
            index = cursor.getColumnIndex(helperDatabase.USER_PASSWORD);
            pUser += cursor.getString(index);
            users.add(pUser);
        }
        db.close();
        return users;
    }

    // Inner class - Helper

    static class HelperDatabase extends SQLiteOpenHelper {

        private Context context;

        private static final String DATABASE_NAME = "LoginDatabase";
        private static final int DATABASE_VERSION = 1;
        private static final String TABLE_1_NAME = "Users";

        private static final String UID = "_id";
        private static final String USER_NAME = "Username";
        private static final String USER_PASSWORD = "Password";
        private static final String USER_ROLE = "Role";

        private static final String CREATE_TABLE_1 =
                "CREATE TABLE " + TABLE_1_NAME + " (" +
                UID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                USER_NAME + " VARCHAR(255), " +
                USER_PASSWORD + " VARCHAR(255), " +
                USER_ROLE + " INTEGER);";

        public HelperDatabase(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            this.context = context;
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            Message.message(context, "onCreate() called for Database");
            try {
                db.execSQL(CREATE_TABLE_1);
                Message.message(context, "Database created");
            } catch (SQLException e) {
                Message.message(context, "" + e);
            }
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Message.message(context, "onUpgrade() called for Database");
            db.execSQL("DROP TABLE IF EXISTS " + TABLE_1_NAME);
            onCreate(db);
        }
    }
}

助手中的所有其他方法都可以正常工作。当我尝试从数据库中唯一的 table 获取用户密码时发生崩溃。我什至没有收到应该从数据库中 return 密码的方法之前的 Toast 消息。

如果我注释掉获取密码的行(如下所示),该应用程序运行正常,但它没有从数据库中获取密码。

//mPasswordDB = database.getPasswordForUser(mUsername);

这里是Logcat:

03-26 11:53:55.677 1886-1886/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                 Process: hr.etfos.kresimirnenadic.loginregisterdatabase, PID: 1886
                                                 android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
                                                     at android.database.AbstractCursor.checkPosition(AbstractCursor.java:426)
                                                     at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
                                                     at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
                                                     at hr.etfos.kresimirnenadic.loginregisterdatabase.AdapterDatabase.getPasswordForUser(AdapterDatabase.java:64)
                                                     at hr.etfos.kresimirnenadic.loginregisterdatabase.MainActivity.onClick(MainActivity.java:46)
                                                     at android.view.View.performClick(View.java:4780)
                                                     at android.view.View$PerformClick.run(View.java:19866)
                                                     at android.os.Handler.handleCallback(Handler.java:739)
                                                     at android.os.Handler.dispatchMessage(Handler.java:95)
                                                     at android.os.Looper.loop(Looper.java:135)
                                                     at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                     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:903)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
03-26 11:53:55.682 689-1061/? W/ActivityManager:   Force finishing activity 1 hr.etfos.kresimirnenadic.loginregisterdatabase/.MainActivity

错误原因行:

 mPassword = cursor.getString(index);

添加行 -

cursor.moveToFirst();

在使用游标获取数据之前。在此行之前添加此行 -

mPassword = cursor.getString(index);

此外,您不需要调用 getWritableDatabase(),因为您只是在读取数据,所以请调用 getReadableDatabase()

尝试使用

mPassword = cursor.getString(1);

(1 代表数据库的特定列),如果有帮助请告诉我