SharedPreferences布尔值始终为false致弹窗重复显示问题求助
嘿,我帮你找到问题所在啦!你的核心问题是SharedPreferences的修改没有被正确提交,导致每次重启App时,布尔值始终是默认的false。咱们一步步拆解问题:
主要错误点
- 提交时机完全错了:你把
editor.commit()放在了UserAgreement()方法的末尾,这会在弹窗刚弹出来的时候就执行了,根本等不到用户点击按钮!此时editor里还没保存用户的操作,等于白提交了。 - 点击按钮后没提交修改:用户点「同意」或「取消」时,你只给editor赋值,但没告诉它“赶紧把修改存到本地”,所以设置根本没生效。
- Toast显示的是旧值:你在put值后立刻去读settings,但这时候修改还没存进去,所以Toast显示的还是false,这会让你误以为设置没成功。
- 上下文引用错误:同意按钮里的Intent用了
this,但这个this指的是点击事件的匿名类,不是你的SplashScreenActivity,会编译报错;取消按钮里的SActivity.this也是同理,得改成SplashScreen.this。
修正后的代码
我把代码调整好了,你可以直接参考:
public static final String PREF_NAME = "AlertDialogPrefs"; private SharedPreferences settings; private SharedPreferences.Editor editor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); // 替换成你的启动页布局 // 初始化SharedPreferences,用MODE_PRIVATE更清晰 settings = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); editor = settings.edit(); boolean hasAgreed = settings.getBoolean("has_agreed", false); if (!hasAgreed) { Toast.makeText(SplashScreen.this, "用户未同意协议,显示弹窗", Toast.LENGTH_LONG).show(); UserAgreement(); } else { Toast.makeText(SplashScreen.this, "用户已同意协议,跳转主页面", Toast.LENGTH_LONG).show(); startActivity(new Intent(SplashScreen.this, HActivity.class)); finish(); // 启动主页面后关闭启动页,避免返回重复触发 } } @SuppressLint("StringFormatInvalid") private void UserAgreement() { final Dialog openDialog1 = new Dialog(SplashScreen.this); openDialog1.setContentView(R.layout.dialog_box_layout); openDialog1.setCanceledOnTouchOutside(false); Button dialogAgreeButton = openDialog1.findViewById(R.id.dialog_agree_button); TextView cancleTV1 = openDialog1.findViewById(R.id.dialog_cancle_tv); dialogAgreeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 同意后提交设置 editor.putBoolean("has_agreed", true); editor.apply(); // 异步提交,比commit()性能更好 // 此时再读取就是最新值了 Toast.makeText(SplashScreen.this, "已同意,当前值:" + settings.getBoolean("has_agreed", false), Toast.LENGTH_LONG).show(); startActivity(new Intent(SplashScreen.this, nextActivity.class)); finish(); openDialog1.dismiss(); // 关闭弹窗避免内存泄漏 } }); cancleTV1.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 取消不需要特意设false,默认就是false,省一步操作 Toast.makeText(SplashScreen.this, "已取消,退出应用", Toast.LENGTH_LONG).show(); moveTaskToBack(true); finish(); openDialog1.dismiss(); } }); openDialog1.setOnKeyListener(new DialogInterface.OnKeyListener() { @Override public boolean onKey(DialogInterface dialogInterface, int keyCode, KeyEvent keyEvent) { if (keyCode == KeyEvent.KEYCODE_BACK && keyEvent.getAction() == KeyEvent.ACTION_UP) { moveTaskToBack(true); finish(); openDialog1.dismiss(); } return false; } }); openDialog1.show(); }
额外优化小建议
- 用
editor.apply()替代editor.commit():apply()是异步提交,不会阻塞主线程,性能更优;如果不需要判断提交是否成功,优先用它。 - 给SharedPreferences和键名起更清晰的名字:比如把文件名改成
AlertDialogPrefs,键名用has_agreed,可读性更强。 - 操作完弹窗记得调用
dismiss():避免内存泄漏。 - 启动新页面后关闭启动页:调用
finish(),防止用户按返回键回到启动页重复触发逻辑。
这样修改后,用户同意协议后设置会被正确保存,下次启动就不会再弹出协议弹窗啦!
内容的提问来源于stack exchange,提问作者Rangamma
相关产品推荐
相关产品推荐

