SharedPreferences 不保存强制关闭应用程序
Posted
技术标签:
【中文标题】SharedPreferences 不保存强制关闭应用程序【英文标题】:SharedPreferences doesn't save on force close app 【发布时间】:2013-03-08 15:42:59 【问题描述】:我有一个带有复选框的登录表单,可以让应用记住LoginActivity
中的电子邮件。如果我按下登录按钮,则电子邮件应使用 AppPreferences
类存储在 SharedPreferences
中。
如果我通过按主页按钮并按返回返回主屏幕,应用程序会记住电子邮件。
但如果我强制关闭应用程序会显示Preferencemanager.getString("value", "default_value");
方法中定义的默认值。
我已经尝试了很多人们在 SO 上提出的建议,但不幸的是,没有一个解决方案奏效。我什至试图通过将所有 SharedPreferences
代码放在一个单独的类中来解决它(参见 this question)。
下面我放了与问题相关的尽可能多的代码。所以LoginActivity
和AppPreferences
这两个类。 LogCat 没有给出错误消息。
在装有 android 4.2.2 Cyanogenmod 10.1 和几个不同模拟器的三星设备 I9100 和 P3110 上都会出现此问题。 (我读到一些带有 HoneyComb 的三星 S 设备无法正确保存 SharedPreferences?)
编辑: 正如我忘记提到的,该项目针对 API 17 和 minSdkVersion = 11。我只在单击登录按钮时保存凭据。编辑 2: 如果手机重启,也会出现此问题
LoginActivity
类:
public class LoginActivity extends Activity
private static final String PREF_REMEMBER_EMAIL = "LoginCredentialsRememberEmail";
private static final String PREF_EMAIL = "LoginCredentialsEmail";
private String mEmail;
private EditText mEmailView;
private CheckBox cbRememberEmail;
private AppPreferences appPreferences;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
appPreferences = new AppPreferences(LoginActivity.this);
loadUserCredentials();
@Override
protected void onResume()
super.onResume();
loadUserCredentials();
@Override
protected void onStart()
super.onStart();
loadUserCredentials();
private void loadUserCredentials()
String rememberEmail = appPreferences.getPreferenceString(PREF_REMEMBER_EMAIL);
String email = appPreferences.getPreferenceString(PREF_EMAIL);
mEmailView = (EditText) findViewById(R.id.email);
mEmailView.setText((rememberEmail == "1") ? email : "");
cbRememberEmail = (CheckBox) findViewById(R.id.cbRememberEmail);
cbRememberEmail.setChecked(rememberEmail == "1" ? true : false);
mEmail = mPassword = "";
private void saveUserCredentials()
try
String rememberemail = (((CheckBox) findViewById(R.id.cbRememberEmail)).isChecked()) ? "1" : "0";
appPreferences.setPreferenceString(PREF_REMEMBER_EMAIL, rememberemail);
String email = (rememberemail == "1") ? mEmail : "";
appPreferences.setPreferenceString(PREF_EMAIL, email);
public void cbRememberEmailClick(View view)
boolean checked = ((CheckBox) findViewById(R.id.cbRememberEmail)).isChecked();
if (checked)
new AlertDialog.Builder(this).setTitle(R.string.remember_email_notification_title).setMessage(R.string.remember_email_notification_message).setPositiveButton(R.string.yes, new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int which)
((CheckBox) findViewById(R.id.cbRememberEmail)).setChecked(true);
).setNegativeButton(R.string.no, new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int which)
((CheckBox) findViewById(R.id.cbRememberEmail)).setChecked(false);
).show();
// ...
AppPreferences
类:
public class AppPreferences
Context context;
private SharedPreferences settings = null;
private static String LOGIN_CREDENTIALS = "com.example.login.credentials";
private static String DEFAULT_STRING = "";
public AppPreferences(Context context)
this.context = context;
settings = PreferenceManager.getDefaultSharedPreferences(context);
private String getKey(String key)
return LOGIN_CREDENTIALS + "." + key;
public String getPreferenceString(String key)
return settings.getString(getKey(key), DEFAULT_STRING);
public void setPreferenceString(String key, String value) throws Exception
SharedPreferences.Editor editor = settings.edit();
editor.putString(getKey(key), (String) value);
editor.commit();
// ...
非常感谢任何帮助,我被困了好几天,现在真的很沮丧。
提前致谢。
敬业
【问题讨论】:
【参考方案1】:您没有显示调用saveUserCredentials
的代码。你应该打电话给onPause
:
@Override
protected void onPause()
super.onPause();
saveUserCredentials();
如果你在后面的生命周期方法之一中调用它(例如onDestroy
),如果应用程序在后台被强制关闭,它将不会被调用。 (如果您仅针对 Honeycomb 及更高版本,则可以将此推迟到 onStop
。)
【讨论】:
我可能错了,但如果你强制关闭应用程序,onPause 或 OnDestory 将不会执行,因为它会完全杀死进程并且任何代码执行都没有完成 @Boardy - 如果您强制关闭前台应用程序,那么您无法保证数据被保存。 (您可以使用 adb 强制关闭前台应用程序,但很难看出如何在设备本身上执行此操作。)如果活动不在前台,则将调用onPause
方法(并且通话完成)。强制关闭会跳过 onStop
(Honeycomb 之前)和 onDestroy
方法调用。
感谢您的输入,但正如我所提到的,如果单击登录按钮,我只会保存电子邮件。很抱歉我忘记了saveUserCredentials
,这个方法在cbRememberEmailClick
中调用。目标是 API 17 (Honeycomb) 和 minSdkVersion = 11【参考方案2】:
我推荐你,把 save 方法放到 onDestroy 方法中
【讨论】:
onDestroy
在后台应用被强制关闭时不会被调用。
我只想在点击登录按钮时保存凭据【参考方案3】:
我通过将字段 rememberEmail
更改为 Boolean
而不是包含 1
或 0
的字符串来修复它。我不知道为什么这不起作用,但我更高兴的是,经过 11 天的挫折之后,这不再是问题了。
我还删除了文件夹/data/data/com.example/shared_prefs/
中的所有首选项文件
LoginActivity
中的代码已更改
// ....
private void loadUserCredentials()
Boolean rememberEmail = appPreferences.getPreferenceBoolean(PREF_REMEMBER_EMAIL);
String email = appPreferences.getPreferenceString(PREF_EMAIL);
mEmailView = (EditText) findViewById(R.id.email);
mEmailView.setText(rememberEmail ? email : "");
cbRememberEmail = (CheckBox) findViewById(R.id.cbRememberEmail);
cbRememberEmail.setChecked(rememberEmail);
private void saveUserCredentials()
try
Boolean rememberEmail = ((CheckBox) findViewById(R.id.cbRememberEmail)).isChecked();
appPreferences.setPreferenceBoolean(PREF_REMEMBER_EMAIL, rememberEmail);
String email = (rememberEmail) ? mEmail : "";
appPreferences.setPreferenceString(PREF_EMAIL, email);
// ....
在AppPreferences
// ....
private String getKey(String key)
key = key.toLowerCase();
return LOGIN_CREDENTIALS + "." + key;
// newly added methods below
public String getPreferenceBoolean(String key)
return settings.getBoolean(getKey(key), DEFAULT_BOOLEAN);
public void setPreferenceBoolean(String key, Boolean value) throws Exception
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean(getKey(key), (Boolean) value);
editor.commit();
// ....
希望你不会犯和我一样的错误;)
【讨论】:
【参考方案4】:如果您在选中复选框时调用saveUserCredentials();
,这应该可以正常工作。还可以尝试在应用程序启动时初始化首选项 obj
【讨论】:
每当单击登录按钮时,我都会调用saveUserCredentials()
,这对我来说似乎更符合逻辑。但是,如果我强制关闭应用程序或重新启动设备,则不会保存任何内容..以上是关于SharedPreferences 不保存强制关闭应用程序的主要内容,如果未能解决你的问题,请参考以下文章
将 ArrayList 保存到 SharedPreferences