You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SharedPreferences布尔值始终为false致弹窗重复显示问题求助

嘿,我帮你找到问题所在啦!你的核心问题是SharedPreferences的修改没有被正确提交,导致每次重启App时,布尔值始终是默认的false。咱们一步步拆解问题:

主要错误点

  • 提交时机完全错了:你把editor.commit()放在了UserAgreement()方法的末尾,这会在弹窗刚弹出来的时候就执行了,根本等不到用户点击按钮!此时editor里还没保存用户的操作,等于白提交了。
  • 点击按钮后没提交修改:用户点「同意」或「取消」时,你只给editor赋值,但没告诉它“赶紧把修改存到本地”,所以设置根本没生效。
  • Toast显示的是旧值:你在put值后立刻去读settings,但这时候修改还没存进去,所以Toast显示的还是false,这会让你误以为设置没成功。
  • 上下文引用错误:同意按钮里的Intent用了this,但这个this指的是点击事件的匿名类,不是你的SplashScreen Activity,会编译报错;取消按钮里的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:27:47