使用SharedPrefs帮助程序在活动之间使用数据

时间:2016-02-18 16:13:21

标签: android android-activity sharedpreferences

我有一个名为SessionManager的类,它应该使用SharedPrefs处理登录的会话。它在很大程度上起作用。我遇到了一个问题,如果我退出(在SharedPrefs中没有任何内容)然后重新登录 - 那么数据就是null。但是,它不是null登录活动 - 但是当我离开登录活动以转到主活动时,那时它就是null。显然,在活动之间使用SharedPrefs存在问题 - 但我不确定我理解为什么/如何。

另一件事 - 如果我关闭应用程序然后再次打开它 - 主要活动中的SharedPref数据是正确的(因为我们在登录一次后开始)。我上面描述的问题只发生在初次登录时。

为了简洁起见,我已经删除了getter方法,因为它们不是问题。

public class SessionManager {

    Context context;
    SharedPreferences pref;
    //Editor for Shared preferences
    SharedPreferences.Editor editor;

    //SharedPref file name
    private static final String PREF_NAME = "current.user";

    //All Shared Preferences Keys
    private static final String IS_LOGIN = "IsLoggedIn";

    //Username
    public static final String KEY_USERNAME = "username";

    //Name
    public static final String KEY_NAME = "name";

    //Email
    public static final String KEY_EMAIL = "email";

    //Constructor for SessionManager
    public SessionManager(Context context) {
        this.context = context;
        pref = this.context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
        editor = pref.edit();
    }

    /**
     * Create login session
     * @param username to store in SharedPrefs
     * @param email to store in SharedPrefs
     */
    public void createLoginSession(String username, String name, String email) {
        /*Store each value into SharedPrefs*/
        editor.putBoolean(IS_LOGIN, true);
        editor.putString(KEY_USERNAME, username);
        editor.putString(KEY_NAME, name);
        editor.putString(KEY_EMAIL, email);

        //Commit changes to SharedPrefs
        editor.commit();
    }
}

我通过这样做在任何活动中调用上述内容:

SessionManager mSession;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_welcome);
    ButterKnife.bind(this);

    mSession = new SessionManager(getApplicationContext());
}

我为每项活动都做了以上事。

我做错了什么?

编辑:以下是我如何访问它并设置值

在LoginActivity上访问它:

// Create a session with values from Firebase--logging shows me these values are correct
mSession.createLoginSession(USERNAME, NAME, EMAIL);

HashMap<String, String> user = mSession.getUserDetails();
String name = user.get(SessionManager.KEY_NAME);
String username = user.get(SessionManager.KEY_USERNAME);
String email = user.get(SessionManager.KEY_EMAIL);
// Logging shows me that the name, username, and email are set properly

然后使用该数据在MainActivity中的导航器中设置标题:

mSession = new SessionManager(getApplicationContext());

HashMap<String, String> user = mSession.getUserDetails();
String namey = user.get(SessionManager.KEY_NAME);
String emaily = user.get(SessionManager.KEY_EMAIL);
String usernamey = user.get(SessionManager.KEY_USERNAME);

2 个答案:

答案 0 :(得分:1)

  

我做错了什么?

我猜你在其他活动中使用不同的上下文。您必须在任何地方使用相同的(getApplicagtionContext()没问题),否则您的SessionManager将访问不同的共享首选项存储(如果您好奇,则为XML文件:)

答案 1 :(得分:1)

我强烈建议在这里使用单例模式。这样,您可以保证在多个类中使用相同的实例。

不确定为什么这似乎是首选implementation of session management

使用示例

public class MainActivity extends AppCompatActivity {

    private SessionManager mSessionManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.mSessionManager = SessionManager.getInstance(getApplicationContext());

        mSessionManager.createLoginSession("tester", "Joe", "sample@example.com");
        boolean isLoggedIn = mSessionManager.getPref().getBoolean(SessionManager.IS_LOGIN, false);
        Log.d("MyTag", String.valueOf(isLoggedIn)); // true

        mSessionManager.logout();
        isLoggedIn = mSessionManager.getPref().getBoolean(SessionManager.IS_LOGIN, false);
        Log.d("MyTag", String.valueOf(isLoggedIn)); // false
    }

}

SessionManager类

public class SessionManager {

    private static SessionManager sInstance;

    private final SharedPreferences pref;
    private final SharedPreferences.Editor editor;

    public static final String PREF_NAME = "current.user";

    public static final String IS_LOGIN = "IsLoggedIn";
    public static final String KEY_USERNAME = "username";
    public static final String KEY_NAME = "name";
    public static final String KEY_EMAIL = "email";

    public static SessionManager getInstance(Context context) {
        if (sInstance == null) {
            sInstance = new SessionManager(context);
        }
        return sInstance;
    }

    private SessionManager(Context context) {
        pref = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
        editor = pref.edit();
    }

    public void createLoginSession(String username, String name, String email) {
        editor.putBoolean(IS_LOGIN, true);
        editor.putString(KEY_USERNAME, username);
        editor.putString(KEY_NAME, name);
        editor.putString(KEY_EMAIL, email);

        editor.commit();
    }

    public void logout() {
        editor.clear();
        editor.putBoolean(IS_LOGIN, false);
        editor.commit();
    }

    public String getLoggedInUsername() {
        String username = null;
        if (pref.contains(KEY_USERNAME) && pref.getBoolean(IS_LOGIN, false)) {
            username = pref.getString(KEY_USERNAME, null);
        }
        return username;
    }

    public SharedPreferences getPref() {
        return pref;
    }
}