Как правильно загружать пользовательские данные из базы данных и передавать их в намеренные дополнения? - PullRequest
0 голосов
/ 12 января 2019

Проект, над которым я работаю, позволяет пользователю зарегистрироваться и войти в систему, и все работает отлично, пока я не заметил что-то не так с кодом. Это не считается ошибкой, потому что компилятор не считает ее ошибкой. Это просто ошибка или как ее называют люди. Итак, вот что случилось. Пользователь входит в свою учетную запись, база данных передает свои данные в intent extras. затем на следующих действиях в верхней части страницы появятся имя пользователя, монеты и драгоценные камни, чтобы пользователь знал, сколько монет у него осталось. Для тестирования я добавил кнопку «Добавить монету» и «Уменьшить монету». Тем не менее, код работает отлично. Но после выхода пользователя из системы и повторной регистрации, coins возвращается к первоначальной сумме. Я знаю проблему, вызванную присвоением значения переменной coin в классе User.java. И все же при входе в систему я добавляю значение по умолчанию для монет и драгоценных камней для пользователя в дополнительных функциях. Я просто не могу найти способ, как поместить значение из базы данных в дополнительные функции при входе пользователя в систему. вот код для входа в систему

buttonLogin.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            //Check user input is correct or not
            if (validate()) {

                //Get values from EditText fields
                String Email = editTextEmail.getText().toString();
                String Password = editTextPassword.getText().toString();
                User player1 = new User(null, null, Email, Password);
                //Authenticate user
                User currentUser = myDb.Authenticate(player1);

                //Check Authentication is successful or not
                if (currentUser != null) {
                    System.out.println("Success");

                    Bundle extras = new Bundle();
                    extras.putString("P_ID", currentUser.getId());
                    extras.putString("P_NAME", currentUser.getName());
                    extras.putInt("P_COINS", currentUser.getCoins());
                    extras.putInt("P_GEMS", currentUser.getGems());
                    Intent intent = new Intent(getApplicationContext(),HomeActivity.class);
                    intent.putExtras(extras);
                    startActivity(intent);
                    finish();
                } else {

                    //User Logged in Failed
                    System.out.println("Failed");
                }
            }
        }
    });

Домашняя деятельность

protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  //Set fullscreen and no title//////////
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);

///////////////////////////////////////

  setContentView(R.layout.home_screen);

  myDb = new DatabaseHelper(this);

  Intent intent = getIntent();
  Bundle extras = intent.getExtras();

  pid = extras.getString("P_ID");
  pname = extras.getString("P_NAME");
  pcoins = extras.getInt("P_COINS");
  pgems = extras.getInt("P_GEMS");

  nametxt = (TextView)findViewById(R.id.playernametext);
  coinstxt = (TextView)findViewById(R.id.playercoinstext);
  gemstxt = (TextView)findViewById(R.id.playergemstext);

  addcoin = (Button)findViewById(R.id.addbtn);
  decoin = (Button)findViewById(R.id.decbtn);

  nametxt.setText(" " +String.valueOf(pname) +" ");
  coinstxt.setText(" Coins : " +String.valueOf(pcoins) +" ");
  gemstxt.setText(" Gems : " +String.valueOf(pgems) +" ");

  addcoin.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      pcoins += 10;
      boolean isUpdate = myDb.updateUser(pid, pname, String.valueOf(pcoins), String.valueOf(pgems));
      if (isUpdate == true) {
        nametxt.setText(" " +String.valueOf(pname) +" ");
  coinstxt.setText(" Coins : " +String.valueOf(pcoins) +" ");
  gemstxt.setText(" Gems : " +String.valueOf(pgems) +" ");
      }
    }
  });

  decoin.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      pcoins -= 10;
      boolean isUpdate = myDb.updateUser(pid, pname, String.valueOf(pcoins), String.valueOf(pgems));
      if (isUpdate == true) {
        nametxt.setText(" " +String.valueOf(pname) +" ");
  coinstxt.setText(" Coins : " +String.valueOf(pcoins) +" ");
  gemstxt.setText(" Gems : " +String.valueOf(pgems) +" ");
      }
    }
  });
}

и, конечно, пользовательский класс

public class User {
  public String id;
  public String userName;
  public String email;
  public String password;
  public int coins = 1000;
  public int gems = 10;

  public User(String id, String userName, String email, String password) {
    this.id = id;
    this.userName = userName;
    this.email = email;
    this.password = password;
  }

  public String getId() {
    return this.id;
  }

  public String getName() {
    return this.userName;
  }

  public void addCoins(int addAmount) {
    this.coins = addAmount;
  }

  public void decCoins(int decAmount) {
    this.coins = decAmount;
  }

  public int getCoins() {
    return this.coins;
  }

  public void addGems(int addAmount) {
    this.gems = addAmount;
  }

  public void decGems(int decAmount) {
    this.gems = decAmount;
  }

  public int getGems() {
    return this.gems;
  }
}

Честно говоря, моему мозгу не хватает логики. Вот почему я пришел сюда, чтобы увидеть, имеет ли смысл мой код. И, пожалуйста, если вы не понимаете, что я имею в виду, просто спросите меня, какие части, и, пожалуйста, не сразу помечайте мой вопрос. Я действительно плохо знаю английский, поверь мне.

1 Ответ

0 голосов
/ 12 января 2019

Я бы рекомендовал только передавать идентификатор пользователя (который никогда не должен изменяться), а затем всегда получать значения монет и т. Д. Из базы данных, а также только изменять их в базе данных (с последующим сбросом отображаемых значений из значений в базе данных). .

В таком случае у вас не возникнет проблемы с манипулированием двумя наборами данных, которые вы затем использовали бы для реальных данных, т. Е. В базе данных.

Рабочий пример

Ниже приведен код, который проходит через основы.

Когда он запускает MainActivity, сразу же запускает LoginActivity при входе в систему, затем он переходит в HomeActivity. Это отображает текущий идентификатор пользователя, имя пользователя, монеты (изначально 0) и драгоценные камни.

Есть 2 кнопки Add10Coins и Add10gems , щелкнув по ним, вы примените новые значения к БД, отображающей обновленные значения. Если вы остановите приложение и запустите его снова, войдите в систему, тогда значения будут такими, как были.

Передача значений разумна, хотя LoginActivity устанавливает 3 Intent Extra значения, только HomeActivity использует только одно (идентификатор пользователя как длинный), но согласно отображаемым значениям все доступны. Если запущено другое действие, все, что вам нужно сделать, это передать идентификатор пользователя через намерение.

Код не то, что я бы назвал сложным, но я бы определенно предложил пройтись по нему и попытаться понять его.

user.java

Я добавил несколько методов, а также добавил несколько констант, это теперь: -

public class User {

    public static final int ADJUSTTYPE_ADD = 1;
    public static final int ADJUSTTYPE_REPLACE = 2;
    public static final int ADJUSTTYPE_MULTIPLY = 3;
    public static final int ADJUSTTYPE_DIVIDE = 4;

    String id;
    String userName;
    String email;
    String password;
    int coins;
    int gems;

    public User(String id, String userName, String email, String password) {

        this.id = id;
        this.email = email;
        //And so on. Don't mind this

    }

    public void setId(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }

    public void setName(String userName) {
        this.userName = userName;
    }

    public String getName() {
        return this.userName;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getEmail() {
        return email;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPassword() {
        return password;
    }


    public void setCoins(int coins) {
        this.coins = coins;
    }

    public int getCoins() {
        return this.coins;
    }

    public void setGems(int gems) {
        this.gems = gems;
    }

    public int getGems() {
        return this.gems;
    }

    public long getLongId() {
        long id;
        try {
            id = Long.valueOf(this.id);
        } catch (Exception e) {
            return -1;
        }
        return id;
    }
}

DatabaseHelper.java

Это было написано с нуля, основываясь не на самой строгой проверке вашего кода, оно будет в значительной степени зависеть от моих методов стилизации / использования, но не в той степени, в которой я бы применил для реальной разработки.

В рамках этого метода AdjustCoinsAndOrGems это то, что используется для обновления драгоценных камней или монет в БД, а также в возвращаемом Пользователе (так что возвращается синхронизированная версия пользователя, а не это используется возвращаемое использование (лично я предпочитаю обращаться к базе данных, если это не проблема (например, заметно влияет на производительность)))

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mygame.db";
    public static final int DBVERSION = 1;

    public static final String TBL_USER = "user";
    public static final String COL_USER_ID = BaseColumns._ID;
    public static final String COL_USER_NAME = "user_name";
    public static final String COL_USER_EMAIL = "user_email";
    public static final String COL_USER_PASWWORD = "user_password";
    public static final String COL_USER_COINS = "user_coins";
    public static final String COL_USER_GEMS = "user_gems";

    public static final String TBL_PLAYER = "player";
    public static final String COL_PLYAER_ID = BaseColumns._ID;
    public static final String COL_PLAYER_OWNINGUSER = "player_owninguser";
    public static final String COL_PLAYER_NAME = "player_name";
    //...... other columns


    SQLiteDatabase mDB;
    public DatabaseHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        String crt_tbl_user = "CREATE TABLE IF NOT EXISTS " + TBL_USER + "(" +
                COL_USER_ID + " INTEGER PRIMARY KEY," +
                COL_USER_NAME + " TEXT NOT NULL UNIQUE," +
                COL_USER_EMAIL + " TEXT NOT NULL UNIQUE," +
                COL_USER_PASWWORD + " TEXT NOT NULL," +
                COL_USER_COINS + " INTEGER," +
                COL_USER_GEMS + " INTEGER" +
                ")";

        String crt_tbl_player = "CREATE TABLE IF NOT EXISTS " + TBL_PLAYER + "(" +
                COL_PLYAER_ID + " INTEGER PRIMARY KEY," +
                COL_PLAYER_NAME + " TEXT NOT NULL," +
                COL_PLAYER_OWNINGUSER + " INTEGER REFERENCES " + TBL_USER + "(" + COL_USER_ID + ")" +
                ")";
        db.execSQL(crt_tbl_user);
        db.execSQL(crt_tbl_player);


    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int i, int i1) {

    }

    /*
        Note core add but not intended to be used directly
        Note this assumes that checks are done to ensure that name, email and password
            have been provided
     */
    private long addUser(Long id, String name, String email, String password, int coins, int gems) {
        ContentValues cv = new ContentValues();
        if (id > 0) {
            cv.put(COL_USER_ID,id);
        }
        if (name.length() > 0) {
            cv.put(COL_USER_NAME,name);
        }
        if (email.length() > 0 ) {
            cv.put(COL_USER_EMAIL,email);
        }
        if (password.length() > 0) {
            cv.put(COL_USER_PASWWORD,password);
        }
        cv.put(COL_USER_COINS,coins);
        cv.put(COL_USER_GEMS,gems);
        if (cv.size() < 1) return -1; //<<<<<<<<<< return if nothing to add
        return mDB.insert(TBL_USER,null,cv);
    }

    /*
        For add with just name, email and password (normal usage)
     */
    public long addUser(String name, String email, String password) {
        return this.addUser(-1L,name,email,password,0,0);
    }

    /*
        For adding a user setting the coins and gems (special usage)
     */
    public long addUserSettingCoinsAndGems(String name, String email, String password, int coins, int gems) {
        return  this.addUser(-1L,name,email,password,coins,gems);
    }

    public User getUser(long id) {
        User rv = new User("-1","",",",""); // Invalid user
        String whereclause = COL_USER_ID + "=?";
        String[] whereargs = new String[]{String.valueOf(id)};
        Cursor csr = mDB.query(TBL_USER,null,whereclause,whereargs,null,null,null);
        if (csr.moveToFirst()) {
            rv.setId(String.valueOf(id));
            rv.setName(csr.getString(csr.getColumnIndex(COL_USER_NAME)));
            rv.setEmail(csr.getString(csr.getColumnIndex(COL_USER_EMAIL)));
            rv.setPassword(csr.getString(csr.getColumnIndex(COL_USER_PASWWORD)));
            rv.setCoins(csr.getInt(csr.getColumnIndex(COL_USER_COINS)));
            rv.setGems(csr.getInt(csr.getColumnIndex(COL_USER_GEMS)));
        }
        csr.close();
        return rv;
    }

    public User getUser(String userid) {
        String whereclause = COL_USER_ID + "=?";

        User rv = new User("-1","",",",""); // Invalid user
        long id;
        try {
            id = Long.valueOf(userid);
        } catch (Exception e) {
            return rv;
        }
        String[] whereargs = new String[]{String.valueOf(id)};

        Cursor csr = mDB.query(TBL_USER,null,whereclause,whereargs,null,null,null);
        if (csr.moveToFirst()) {
            rv.setId(String.valueOf(id));
            rv.setName(csr.getString(csr.getColumnIndex(COL_USER_NAME)));
            rv.setEmail(csr.getString(csr.getColumnIndex(COL_USER_EMAIL)));
            rv.setPassword(csr.getString(csr.getColumnIndex(COL_USER_PASWWORD)));
            rv.setCoins(csr.getInt(csr.getColumnIndex(COL_USER_COINS)));
            rv.setGems(csr.getInt(csr.getColumnIndex(COL_USER_GEMS)));
        }
        csr.close();
        return rv;
    }

    public User getUser(String email, String password) {
        User rv = new User("-1","","","");
        String whereclause = COL_USER_EMAIL + "=? AND " + COL_USER_PASWWORD + "=?";
        String[] whereargs = new String[]{email,password};
        Cursor csr = mDB.query(TBL_USER,null,whereclause,whereargs,null,null,null);
        if (csr.moveToFirst()) {
            rv.setId( String.valueOf(csr.getLong(csr.getColumnIndex(COL_USER_ID))));
            rv.setName(csr.getString(csr.getColumnIndex(COL_USER_NAME)));
            rv.setEmail(csr.getString(csr.getColumnIndex(COL_USER_EMAIL)));
            rv.setPassword(csr.getString(csr.getColumnIndex(COL_USER_PASWWORD)));
            rv.setCoins(csr.getInt(csr.getColumnIndex(COL_USER_COINS)));
            rv.setGems(csr.getInt(csr.getColumnIndex(COL_USER_GEMS)));
        }
        csr.close();
        return rv;
    }

    public User adjustCoinsAndOrGems(User u, int coins, int coin_adjustmode, int gems, int gem_adjustmode) {
        ContentValues cv = new ContentValues();
        User rv;
        User user_fromDB = getUser(u.getId());
        if (user_fromDB.id.equals("-1")) return u; // User not found so return
        switch (coin_adjustmode) {
            case User.ADJUSTTYPE_REPLACE:
                cv.put(COL_USER_COINS,coins);
                break;
            case User.ADJUSTTYPE_ADD:
                if (coins != 0) {
                    cv.put(COL_USER_COINS,user_fromDB.getCoins() + coins);
                }
                break;
            case User.ADJUSTTYPE_MULTIPLY:
                if (coins > 0) {
                    cv.put(COL_USER_COINS,user_fromDB.getCoins() * coins);
                }
                break;
            case User.ADJUSTTYPE_DIVIDE:
                if (coins > 0) {
                    cv.put(COL_USER_COINS,user_fromDB.getCoins() / coins);
                }
                break;
        }
        switch (gem_adjustmode) {
            case User.ADJUSTTYPE_REPLACE:
                cv.put(COL_USER_GEMS,gems);
                break;
            case User.ADJUSTTYPE_ADD:
                if (gems != 0) {
                    cv.put(COL_USER_GEMS,user_fromDB.getGems() + gems);
                }
                break;
            case User.ADJUSTTYPE_MULTIPLY:
                if (gems > 0) {
                    cv.put(COL_USER_GEMS,user_fromDB.getGems() * gems);
                }
                break;
            case User.ADJUSTTYPE_DIVIDE:
                if (gems > 0) {
                    cv.put(COL_USER_GEMS,user_fromDB.getGems() / gems);
                }
                break;
        }
        if (cv.size() < 1) return u;
        String whereclause = COL_USER_ID + "=?";
        String[] whereargs = new String[]{u.getId()};
        mDB.update(TBL_USER,cv,whereclause,whereargs);
        return getUser(user_fromDB.getId());
    }

    public boolean authenticateUser(String email, String password) {
        User u = getUser(email,password);
        return (u.getLongId() > 0);
    }
}

MainActivity.java

Очень простое действие, которое запускает LoginActivity и когда, наконец, возвращается, ничего не делает (так что вы можете также убить приложение).

public class MainActivity extends AppCompatActivity {

    TextView mMessage;
    DatabaseHelper mDB;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mMessage = this.findViewById(R.id.message);
        mDB = new DatabaseHelper(this);
        addSomeTestingUsers();


        // Immediately start Login Activity
        Intent i = new Intent(MainActivity.this,LoginActivity.class);
        startActivity(i);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mMessage.setText("Welcome back");
    }

    private void addSomeTestingUsers() {
        if (DatabaseUtils.queryNumEntries(mDB.getWritableDatabase(),DatabaseHelper.TBL_USER) > 0) return;
        mDB.addUser("Fred","fred@fredmal.com","password");
        mDB.addUser("Mary","mary@mary.email.com","password");
    }
}

LoginActivity

Это довольно простое замечание: в настоящее время вам необходимо войти в систему, а электронные письма и пароли для двух пользователей закодированы в MainActivity. При правильной поставке HomeActivivty запускается: -

открытый класс LoginActivity расширяет AppCompatActivity {

public static final String INTENTKEY_USERNAME = "IK_USERNAME";
public static final String INTENTKEY_USERID = "IK_USERID";
public static final String INTENTKEY_STRINGUSERID = "IK_USERIDSTRING";

Button mloginbtn;
EditText mEmail,mPassword;
Context mContext;
DatabaseHelper mDB;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    mContext = this;
    mloginbtn = this.findViewById(R.id.loginbtn);
    mEmail = this.findViewById(R.id.email);
    mPassword = this.findViewById(R.id.password);
    mDB = new DatabaseHelper(this);

    mloginbtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            handleAuthentication();
        }
    });
}

private void handleAuthentication() {
    if (mDB.authenticateUser(mEmail.getText().toString(),mPassword.getText().toString())) {
        User u = mDB.getUser(mEmail.getText().toString(),mPassword.getText().toString());
        Intent i = new Intent(mContext,HomeActivity.class);
        i.putExtra(INTENTKEY_USERNAME,u.getName());
        i.putExtra(INTENTKEY_USERID,u.getLongId());
        i.putExtra(INTENTKEY_STRINGUSERID,u.getId());
        startActivity(i);
        finish();
    }
}

HomeActivity

Для краткости это использовалось для отображения монет и драгоценных камней, оно довольно простое и основано на методах DatabaseHelper для выполнения большей части работы.

public class HomeActivity extends AppCompatActivity {

    TextView mUserameTextView, mUseridTextView, mCoinsTextView, mGemsTextView;
    Button mAdd10Coins, mAdd10Gems,mDone;
    User mUser;
    long mUserid;
    Context mContext;
    DatabaseHelper mDB;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        mContext = this;
        mDB = new DatabaseHelper(mContext);

        mUserameTextView = this.findViewById(R.id.username);
        mUseridTextView = this.findViewById(R.id.userid);
        mCoinsTextView = this.findViewById(R.id.coins);
        mGemsTextView = this.findViewById(R.id.gems);

        Intent i = this.getIntent();
        mUserid = i.getLongExtra(LoginActivity.INTENTKEY_USERID,-1);
        mUser = mDB.getUser(mUserid);
        refreshDisplay();
        initButtons();
    }

    private void initButtons() {
        mAdd10Coins = this.findViewById(R.id.add10coins);
        mAdd10Coins.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mDB.adjustCoinsAndOrGems(mUser,10,User.ADJUSTTYPE_ADD,0,User.ADJUSTTYPE_ADD);
                mUser = mDB.getUser(mUserid);
                refreshDisplay();
            }
        });
        mAdd10Gems = this.findViewById(R.id.add10gems);
        mAdd10Gems.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mDB.adjustCoinsAndOrGems(mUser,0, User.ADJUSTTYPE_ADD,10,User.ADJUSTTYPE_ADD);
                mUser = mDB.getUser(mUserid);
                refreshDisplay();
            }
        });

        mDone = this.findViewById(R.id.done);
        mDB = new DatabaseHelper(mContext);
        mDone.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });
    }

    private void refreshDisplay() {
        mUseridTextView.setText(mUser.getId());
        mUserameTextView.setText(mUser.getName());
        mCoinsTextView.setText(String.valueOf(mUser.getCoins()));
        mGemsTextView.setText(String.valueOf(mUser.getGems()));
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...