【问题标题】:Shared Preferences reset data when app is force closed or device is restarted当应用程序被强制关闭或设备重新启动时,共享首选项会重置数据
【发布时间】:2013-03-12 05:23:39
【问题描述】:

我正在开发一个应用程序,其中我将usernamepassword 存储在SharedPreferences 中。一切对我来说都很好,存储和检索值。但我发现当我重新启动设备或应用程序被强制关闭时,存储在SharedPreferences 中的值被重置。当我再次启动我的应用程序时,我在 SharedPreferences 键中得到空值。这是我为存储值所做的:

SharedPreferences emailLoginSP;

emailLoginSP = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
emailLoginSP.edit().putString("prefEmailId", email_text).commit();
emailLoginSP.edit().putString("prefUserId", userIDToken).commit();
emailLoginSP.edit().putString("prefAccess_token", accessToken).commit();

Intent i = new Intent(LoginWithEmail.this,UserInfoActivity.class);
i.putExtra("acess_token", accessToken);
i.putExtra("user_id", userIDToken);
i.putExtra("emailID", email_text);
startActivity(i);

而且,这就是我正在重新尝试它的方式:

SharedPreferences emailLoginSP = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

loginEmail = emailLoginSP.getString("prefEmailId", null);
loginUserId = emailLoginSP.getString("prefUserId", null);
loginAccessToken = emailLoginSP.getString("prefAccess_token", null);

到目前为止,一切正常。 我再次说明我的问题,即当我强制关闭或重新启动设备时我得到空值。我们可以将其永久存储在应用程序内存中吗?或者,我在这里做错了什么?

任何帮助将不胜感激。

【问题讨论】:

  • 当您在 SP 中存储值后重新启动设备时,它不会返回 NULL,看来您还有其他问题。能告诉我们你在哪里逼近吗?
  • 我没有强行关闭。我已通过设置->应用程序强制停止该应用程序并从那里强制停止它。当我同时重新启动手机或强制停止它时,我的值将变为空。
  • @Anupam 我下面的解决方案将保留强制停止中的值,当您重新启动设备等时。SharedPreferences 将值存储到 XML,因此无论应用程序如何被销毁它们都将永远是保留stackoverflow.com/questions/6146106/…您使用的存储或检索代码一定有问题
  • 事实证明这也可能是由无效的首选项键引起的,例如包含换行符的键:stackoverflow.com/questions/28385132/…

标签: android sharedpreferences


【解决方案1】:

我有一个登录屏幕,并希望在应用关闭/销毁/电话/等后,该应用在内部屏幕上显示为保持“登录”状态。

我有一个Preferences 对象来保存LoginRegister 之后的值。我在所有关键屏幕onResume() 方法中读取了偏好值。

登录后(例如):

SharedPreferences app_preferences = PreferenceManager.getDefaultSharedPreferences(activity);
SharedPreferences.Editor editor = app_preferences.edit();
editor.putString("sessionId", application.currentSessionId);
editor.putString("userId", application.currentUserId);
editor.putString("userEmail", application.currentUserEmail);
editor.putString("siteUserId", application.currentSiteUserId);
editor.commit();

在活动的 onResume() 内: (即,在内部屏幕内)

SharedPreferences app_preferences = PreferenceManager.getDefaultSharedPreferences(activity);
application.currentSessionId = app_preferences.getString("sessionId", "");
application.currentUserId = app_preferences.getString("userId", "");
application.currentUserEmail = app_preferences.getString("userEmail", "");
application.currentSiteUserId = app_preferences.getString("siteUserId", "");

注意。我有应用程序“全局”变量,即application.currentSessionId,你可以替换你的变量

尝试类似的方法,也许您无法正确保存或检索值,因为 SharePreferences 应该可以工作

【讨论】:

  • 对于未来的读者,SharedPreferences.Editor 使用构建器模式来构建提交事务。 editor.putString(k,v).putLong(k2,n).commit();在 commit() 之后,您应该使用新的 Editor 或在重用之前调用 editor.clear()。
  • 我遇到了同样的问题。我的代码和你上面提到的一样,只有一个区别是 u = URLDecoder.decode(u,"UTF-8"); u 是用户的电子邮件 ID。因为这段代码,我会遇到同样的问题吗?
【解决方案2】:

嗨! 对我有用的解决方案!

Solution 1 Solution 2

解决方案 1:

  SharedPreferences sharedPreferences = getSharedPreferences("namefile",               
    Context.MODE_PRIVATE);//store or retrieved file "namefile.xml".
    /*or 
   SharedPreferences sharedPreferences    
   =getActivity().getSharedPreferences("namefile", Context.MODE_PRIVATE); 
   (use Shared Preferences in Fragment)*/
   String getValueFromKey = sharedPreferences.getString("yourKey",new   
   String());
   //Log.d("printf:",getValueFromKey );
   getValueFromKey ="Hahaha"; /*  Edit value    
   or Do nothing …… */
   SharedPreferences.Editor editor = sharedPreferences.edit();
   editor.clear(); //[important] Clearing your editor before using it.
   editor.putString("yourKey", getValueFromKey);
   editor.commit();

解决方案 2:

SharedPreferences sharedPreferences = getSharedPreferences("namefile",     
  Context.MODE_PRIVATE);//store or retrieved file "namefile.xml".
/*or 
SharedPreferences sharedPreferences = 
getActivity().getSharedPreferences("namefile", Context.MODE_PRIVATE); 
(use Shared Preferences in Fragment)
*/
Set<String> getListValueFromKey =
sharedPreferences.getStringSet("yourKey",new HashSet<String>());
getListValueFromKey.add("Hahaha");
getListValueFromKey.add("Kakaka");
getListValueFromKey.add("Hohoho");
/*  Add value or Do nothing …… */
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.clear(); //[important] Clearing your editor before using it.
editor.putStringSet("yourKey", getListValueFromKey);
editor.commit();

我遇到了和你一样的问题,这对我有用。对于我的整个代码示例,请参阅

【讨论】:

  • 方案二中的代码不好;您不能修改和重新保存从getStringSet 获得的值。设置the documentation
【解决方案3】:

改为:

SharedPreferences emailLoginSP;
SharedPreferences.Editor SPEdit;

emailLoginSP = getSharedPreferences("pref_file_name",MODE_PRIVATE);
SPEdit = emailLoginSP.edit();

SPEdit.putString("prefEmailId", email_text);
SPEdit.putString("prefUserId", userIDToken);
SPEdit.putString("prefAccess_token", accessToken);
SPEdit.commit();

注意:这是未经测试且来自内存,因此可能存在错误。

您想最小化.commit() 调用,这就是为什么最后只有一个。

pref_file_name 可以是任何你想要的,小写字母,开头没有数字等。

【讨论】:

    【解决方案4】:

    请看我已经完成了如下操作。

            sharedPreferences = PreferenceManager
                    .getDefaultSharedPreferences(getApplicationContext());
            editor = sharedPreferences.edit();
            isPaidVerison = sharedPreferences.getInt("isPaidVerison", 0);
    
    
            editor.putInt("isPaidVerison", 1);
            editor.commit();
    

    这很好用。 数据将保留在 Sharedprefrences 中,直到不会重新安装应用程序或直到不会清除数据。

    我以这种方式检索数据。

           isPaidVerison = sharedPreferences.getInt("isPaidVerison", 0);
    

    【讨论】:

      【解决方案5】:

      确保您使用相同的文件进行保存和检索。 这让我看起来很愚蠢:(

      // When saving
      public SharedPreferences.Editor getEditor(Activity activity, int mode) {
          SharedPreferences sharedPref = activity.getApplicationContext().getSharedPreferences(PreferenceConstants.SWAGGER_USER_PREFS, mode);
          SharedPreferences.Editor editor = sharedPref.edit();
          return editor;
      }
      
      
      // When getting it
          public SharedPreferences getSharedPref(Activity activity, int mode) {
                  SharedPreferences sharedPref = activity.getSharedPreferences(PreferenceConstants.SWAGGER_USER_PREFS, mode);
                  return sharedPref;
              }
      

      【讨论】:

        【解决方案6】:

        如果您想尝试共享首选项以外的方法,则可以使用文件写入值,然后从中检索值。声明一个文本文件 emailLogin.txt 并使用它来写入数据。

                   try {
                        Context context = MainActivity.this;
                        OutputStreamWriter out=
                                new OutputStreamWriter(context.openFileOutput(EMAILLOGIN, 0));
        
                        out.write(email_text);                   
                        out.write("\r\n");
                        out.write(userIDToken);                   
                        out.write("\r\n");
                        out.write(accessToken);                   
                        out.write("\r\n");
        
                        out.close();
                    } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } 
        

        写入文件后,您可以执行以下操作来读取文件。

           File file = this.getFileStreamPath(EMAILLOGIN);
        
                    if(file.exists())
                    {
                        try {
                            InputStream in=openFileInput(NUMBERS);
        
                            if (in!=null) {
                                InputStreamReader tmp=new InputStreamReader(in);
                                BufferedReader reader=new BufferedReader(tmp);
                                String str;
                                String strcount[]= new String[20];                                                        
        
                                java.util.Arrays.fill(strcount, 0, 10, "");
                                while ((str = reader.readLine()) != null) {                       
                                    strcount[linecount]=str;                              
                                }
        
                                loginEmail = strcount[0];
                                loginUserId = strcount[1];
                                loginAccessToken = strcount[2];
        
                                in.close();              
                            }
                        } catch (FileNotFoundException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
        

        这将确保即使您的应用强制关闭或您的设备重新启动,您仍然可以从文件中读取所需的值。

        【讨论】:

        • 这不是一个好的解决方案,因为SharePreferences 已经存储到一个文件中,它为您存储在 XML 中。即使在您所说的“重新启动”之后,它也会保留值。这几乎值得投票否决。在这里阅读:stackoverflow.com/questions/6146106/…。我建议在您自己的项目 user1721904 中实施 SharedPreferences 作为您的重新发明轮子。希望对伴侣有所帮助
        • LOL .. 仅仅因为您希望选择您的答案并不意味着您应该对其他人的答案发表这样的评论.. 顺便说一句,我在答案开头提到他可以尝试如果他想使用不同的方法,我没有阻止他使用 SharedPreferences ..
        • 不错的 BM。如果你的答案是错误的,我会告诉你。它是为你好,但如果你想忽略我也不担心
        猜你喜欢
        • 2011-06-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-05
        • 1970-01-01
        • 1970-01-01
        • 2017-09-12
        • 1970-01-01
        相关资源
        最近更新 更多