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

Android中立即重启App后SharedPreferences状态保存不生效问题

问题分析与解决方案
  • 核心问题不在重启方式,而是SharedPreferences的异步写入机制
    你用的apply()是异步写入磁盘的方法,调用后会立即返回,但实际的磁盘写入操作是在后台线程执行的。如果立刻调用Runtime.getRuntime().exit(0)杀死进程,后台的写入操作可能还没完成,新值根本没真正保存到磁盘,重启后自然读到的是旧值。
    延迟100ms能生效,只是刚好给了异步写入足够的时间完成,但这种方式不可靠——不同设备性能差异大,没法保证在所有设备上都能正常工作。

  • 当前重启方式的小问题
    Runtime.getRuntime().exit(0)属于强制终止进程,虽然能实现重启,但不符合Android系统的规范,更推荐用系统提供的Activity栈管理方式来重启。不过这不是导致数据没保存的根本原因。

  • 正确的解决办法

    1. 替换异步写入为同步写入
      把updateIsCheckedInRegistry里的apply()换成commit():commit()是同步写入磁盘的方法,会等到数据真正写入完成后才返回,调用完就能确保新值已经持久化,之后立刻重启也能读到正确的值。
      修改后的代码:

      private void updateIsCheckedInRegistry(boolean isChecked) {
          Log.w("+++", "+++ updateIsCheckedInRegistry(), isChecked: "+isChecked);
      
          PreferenceManager.getDefaultSharedPreferences(this).edit()
                  .putBoolean(PREFS_DEMO_IS_CHECKED, isChecked).commit(); // 替换apply为commit
      }
      
    2. 优化重启代码(可选,更符合Android规范)
      去掉强制进程退出的代码,改用Activity栈清理的方式重启:

      public static void restartApp(Context context) {
          PackageManager packageManager = context.getPackageManager();
          Intent intent = packageManager.getLaunchIntentForPackage(context.getPackageName());
          if (intent != null) {
              intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
              context.startActivity(intent);
              if (context instanceof Activity) {
                  ((Activity) context).finishAffinity(); // 关闭当前应用所有栈内Activity
              }
          }
      }
      

    这样既保证了数据100%保存完成,又用更规范的方式重启App,完全不需要依赖不可靠的延迟操作。

内容的提问来源于stack exchange,提问作者lannyf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 15:15:38