在已经存在的 SharedPreference 值中更改数据类型

Changing Datatype within an already existing SharedPreference Value

我正在清理一些非常旧的应用程序中的错误编码选择。在我做的第一个应用程序中,它有一个用户登录名。所以,我使用 SharedPreferences 来存储 user_id。这应该一直是 long。不幸的是,我最初将其存储为 String

我要回去更正这个问题。但是,我当然得到 ClassCastException 因为我试图将 String 作为 long.

这是我的代码,说明它在更改后如何工作:

public static void setLoggedInUserId(Context ctx, long id) {
    Editor editor = getSharedPreferences(ctx).edit();
    editor.putLong(PREF_LOGGEDIN_USER_USERID, id);
    editor.apply();
}

public static long getLoggedInUserId(Context ctx) {
    // need to handle String to long conversion here?
    return getSharedPreferences(ctx).getLong(PREF_LOGGEDIN_USER_USERID, 0);
}

处理此问题的最简洁方法是什么,以便它对用户尽可能透明(如果可能,我不想强​​制注销)。

编辑

我正在打字,这是一个好的解决方案吗?

return Long.valueOf(getSharedPreferences(ctx).getString(PREF_LOGGEDIN_USER_USERID, 0));

一个问题:这只会在第一次解决旧数据时起作用;因为在那之后,偏好将是基于 setter 方法的 long

下一个最佳选择:我可以测试存储在 preference 中的类型,也许可以使用 typeof

在第一次调用此值之前将其放入您的 MainActivity

        if(!prefs.getBoolean("ConversionDone", false)){
            String currentStringValue = prefs.String(PREF_LOGGEDIN_USER_USERID, 0);
            prefs.edit().remove(PREF_LOGGEDIN_USER_USERID).commit();
            prefs.edit().putLong(PREF_LOGGEDIN_USER_USERID, Long.parseLong(currentStringValue)).commit();
            prefs.edit().putBoolean("ConversionDone", true).commit();
        }

您可以在下次更新时将其删除。

  1. getLoggedInUserId中,捕获class转换异常

  2. 读取共享首选项的(String)值并用Long.parseLong()

  3. 转换
  4. 创建一个编辑器,put long 值,然后提交。

此代码将 运行 恰好一次,然后您将不再需要担心边缘情况。