正在运行的项目允许用户注册和登录,并且一切正常,直到我发现代码有问题。它不算作错误,因为编译器认为它不是错误。它只是一个错误或任何人称之为的错误。所以这就是发生的事情。用户登录到其帐户后,数据库会将其数据传输到intent extras
中。然后在接下来的活动中,用户名,硬币和宝石会显示在页面顶部,以便用户知道他们还剩下多少硬币。出于测试目的,我添加了添加硬币和减少硬币按钮。仍然,代码运行完美。但是在用户注销并重新登录后,coins
将恢复为原始金额。我知道将值放在User.java
类的coin变量中引起的问题。仍然在登录时,我将用户的硬币和宝石的默认值放在意向附加中。我只是无法找到如何在用户登录时将数据库中的值放入意向附加中的方法。
这是登录活动的代码
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;
}
}
老实说,我的大脑缺乏逻辑。这就是为什么我来这里,看看我的代码是否有意义。 而且,如果您不明白我的意思,请问我哪些部分,请不要立即标记我的问题。我真的英语不好,相信我。
答案 0 :(得分:2)
我建议仅传递用户标识(永远不要更改),然后始终从数据库中获取值硬币等,并且也仅在数据库中进行更改(随后通过从数据库中的值重置显示的值)
那么您就不会遇到尝试处理两组数据的问题,而您将依赖于真实数据即数据库中的真实数据。
以下是一些基本的代码。
启动MainActivity时,登录时立即启动LoginActivity,然后将您带到HomeActivity。显示当前的用户名,用户名,硬币(最初为0)和宝石。
有两个按钮 Add10Coins 和 Add10gems ,单击它们会将新值应用于显示更新值的数据库。如果停止应用程序并重新运行,请登录,然后值将保持不变。
明智地传递值,尽管LoginActivity设置了3个Intent Extra值,但HomeActivity仅使用了一个(用户ID长),但是按照值显示,所有值都是可以访问的。如果启动了另一个活动,那么您要做的就是通过意图传递用户ID。
代码不是我所说的复杂代码,但我当然建议您仔细阅读并理解它。
我添加了一些方法,还添加了一些常量,现在是:-
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;
}
}
这是基于对代码的最严格检查而从头开始编写的,它在很大程度上会受到我的样式/使用技巧的影响,但不会受到我申请实际开发的程度的影响。
在此方法之内 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);
}
}
一个非常简单的活动,它启动了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");
}
}
这很简单,请注意,您必须先登录,并且这2个用户的电子邮件和密码已在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();
}
}
为简便起见,它已被用来显示硬币和宝石,这是非常基本的,并且依靠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()));
}
}