2013-03-08 115 views
1

我有一个复选框的登录表单让应用程序记住LoginActivity中的电子邮件。如果按下“登录”按钮,则应使用类AppPreferences将电子邮件存储在SharedPreferences中。SharedPreferences不保存在强制关闭应用程序

如果我通过按回家按钮并按回来返回到主屏幕,应用程序会记住电子邮件。

但是,如果我强制关闭应用程序显示Preferencemanager.getString("value", "default_value");方法中定义的默认值。

我已经尝试了很多人提出的建议,但不幸的是没有解决方案。我甚至试图通过将所有SharedPreferences代码放在单独的类中来解决它(请参阅this question)。

下面我把尽可能多的代码相关的问题。所以这两个类LoginActivityAppPreferences。没有LogCat给出的错误信息。

在三星设备I9100和P3110与Android 4.2.2 Cyanogenmod 10.1和几个不同的模拟器发生此问题。 (我读了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(); 
    } 
// ... 
} 

任何帮助非常感谢,我在这个日子里困住了,现在真的很沮丧。

在此先感谢。

Dediqated

回答

1

我固定它的开始偏好OBJ。我不知道为什么这不起作用,但我对事实感到高兴,即在经历了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(); 
} 
// .... 

我希望你不要再犯同样的错误和我一样;)

1

我建议你,把保存方法进入的onDestroy方法

+2

'onDestroy' will no当后台应用程序强制关闭时不会被调用。 – 2013-03-08 15:59:16

+0

我只想保存登录按钮上的凭证点击 – Dediqated 2013-03-11 09:42:22

3

你不显示调用saveUserCredentials的代码。你应该把它在:

@Override 
protected void onPause() { 
    super.onPause(); 
    saveUserCredentials(); 
} 

如果您在以后的生命周期方法(如onDestroy)一个调用它,它不会被调用该应用是否强制关闭,同时在后台运行。 (如果您仅针对Honeycomb及更高版本,则可将其推迟至onStop。)

+3

我可能是错的,但如果你强制关闭应用程序,onPause或OnDestory将不会执行,因为它会完全杀死进程并且没有执行任何代码 – Boardy 2013-03-08 15:50:27

+1

@Boardy - 如果你强制关闭一个前台应用程序,那么你可以做很多事情来保证数据的保存。 (你可以用adb强制关闭一个前台应用程序,但很难看到你如何在设备本身上做到这一点。)如果这个activity不在前台,那么它的onPause方法将被调用(并且呼叫完成)。这是'onStop'(前蜂窝)和'onDestroy'方法调用,它们在关闭时被跳过。 – 2013-03-08 15:56:23

+0

感谢您的输入,但正如我所说,我只保存电子邮件,如果登录按钮被点击。对不起,我忘了'saveUserCredentials',这个方法在'cbRememberEmailClick'中调用。目标是API 17(蜂窝)和minSdkVersion = 11 – Dediqated 2013-03-11 09:41:30

0

如果您在调用saveUserCredentials();时勾选了复选框,则应该完美地工作。还尝试通过改变字段rememberEmailBoolean代替含有10字符串初始化应用

+0

我每次登录按钮被点击时调用'saveUserCredentials()',对我来说似乎更多的逻辑。但是,如果我强制关闭应用程序或重新启动设备没有保存.. – Dediqated 2013-03-19 07:32:28