Android应用关闭后记住登录复选框失效及登出功能异常
记住登录功能异常排查与修复
现存问题
当前代码存在5处核心逻辑错误,和数据库无关,均为SharedPreferences使用与生命周期顺序问题:
- 控件初始化顺序颠倒:执行「读取登录状态填充账号密码、勾选复选框」逻辑时,还未通过
findViewById绑定输入框、复选框控件,此时控件引用为空,相关逻辑完全不生效,甚至可能触发空指针崩溃。 - SharedPreferences多实例数据不互通:先后创建了两个独立的SharedPreferences文件:名为
Data的文件用来读取ISLOGGEDIN登录标记,名为account的文件用来存储账号密码,两个文件数据完全隔离,读登录状态的位置根本拿不到存储的账号信息。 - 数据未提交/逻辑写反:勾选「记住登录」分支中,对
Data文件的editor存入ISLOGGEDIN=true后没有调用commit()/apply()提交,数据不会持久化到磁盘;未勾选「记住登录」的分支中,先写入登录标记再调用clear()清空所有数据,等于没有写入任何持久化信息,且该分支本就不该保存长期登录状态。 - 自动跳转逻辑缺失:判断
ISLOGGEDIN为true后,仅做了界面填充,没有编写跳转到HomeActivity的逻辑,就算登录状态读取正确,也会一直停留在登录页。 - 登出逻辑不完整:当前登出代码仅做了页面跳转,没有清空持久化存储的登录状态标记,跳转后存储的登录信息依旧存在。
修复代码
1. 登录页onCreate逻辑修正
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 第一步:先绑定所有控件,再做后续逻辑操作 btnRegister = (Button) findViewById(R.id.buttonSignup); edtAccount = (EditText) findViewById(R.id.editTextAccount); edtPassword = (EditText) findViewById(R.id.editTextPassword); btnLogin = (Button) findViewById(R.id.buttonLogin); checkBoxRemember = (CheckBox) findViewById(R.id.checkBoxRemember); // 统一使用同一个SharedPreferences文件,不要创建多个实例 SharedPreferences sharedPreferences = getSharedPreferences("user_config", MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); // 读取登录状态,已登录直接跳转主页,不需要留在登录页 boolean isLoggedIn = sharedPreferences.getBoolean("ISLOGGEDIN", false); if (isLoggedIn) { startActivity(new Intent(MainActivity.this, HomeActivity.class)); finish(); return; } db = new Database(this); btnRegister.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(MainActivity.this, RegisterActivity.class)); } }); btnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String account = edtAccount.getText().toString().trim(); String password = edtPassword.getText().toString().trim(); if (account.isEmpty() || password.isEmpty()){ Toast.makeText(MainActivity.this, "Không được để trống tài khoản và mật khẩu", Toast.LENGTH_SHORT).show(); return; } Boolean loginResult = db.checkUserNamePassword(account, password); if (loginResult) { Intent intent = new Intent(MainActivity.this, HomeActivity.class); intent.putExtra("account", account); if (checkBoxRemember.isChecked()){ // 勾选记住登录:持久化存储登录标记、账号密码 editor.putBoolean("ISLOGGEDIN", true); editor.putString("account", account); editor.putString("password", password); editor.apply(); } else { // 未勾选记住登录:清空之前的持久化登录信息,不存长期标记 editor.clear(); editor.apply(); } startActivity(intent); finish(); } else { Boolean userExist = db.checkUserName(account); if (userExist){ Toast.makeText(MainActivity.this, "Sai mật khẩu!", Toast.LENGTH_SHORT).show(); edtPassword.setError("invalid password!"); } else { Toast.makeText(MainActivity.this, "Account does not exist", Toast.LENGTH_SHORT).show(); edtAccount.setError("Tài khoản không tồn tại!"); } } } }); }
2. 登出逻辑修正
登出时需要先清空持久化的登录状态,再跳转回登录页,同时清空任务栈防止返回键直接回到主页:
final AlertDialog.Builder builder = new AlertDialog.Builder(HomeActivity.this); builder.setMessage(R.string.logout_message); builder.setNegativeButton("Đăng xuất", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { // 清空登录状态 SharedPreferences sharedPreferences = getSharedPreferences("user_config", MODE_PRIVATE); sharedPreferences.edit().clear().apply(); // 跳转登录页并清空任务栈 Intent intent = new Intent(HomeActivity.this, MainActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(intent); finish(); } }); // 不要遗漏show方法,否则对话框不会弹出 builder.show();
内容的提问来源于stack exchange,提问作者Bùi Minh Thương
相关产品推荐
相关产品推荐

