将枚举保存到SharedPreference

时间:2013-02-07 12:07:35

标签: android

我想知道,用于将Enum保存到SharedPrefereces的常用方法是什么?目前,我正在使用gson将枚举转换为String,然后将其保存到SharedPrefereces

    Gson gson = new Gson();
    // country is an enum.
    String json_country = gson.toJson(country);
    sharedPreferences.edit().putString(COUNTRY, json_country);

我在想,这是一个好方法吗?还有更好的办法吗?

5 个答案:

答案 0 :(得分:43)

您可以为它使用一个简单的String,然后使用valueOf方法提取值。这是一个例子:

public enum MyEnum {
    ENUM1, ENUM2, ENUM3, ENUM4;

    public static MyEnum toMyEnum (String myEnumString) {
        try {
            return valueOf(myEnumString);
        } catch (Exception ex) {
                // For error cases
            return ENUM1;
        }
    }
}

public void setMyEnum(Context context, MyEnum myEnum) {
    SharedPreferences sp = context.getPreferences(this.MODE_PRIVATE);
    SharedPreferences.Editor editor = sp.edit();
    editor.putString("MyEnum", myEnum.toString());
    editor.commit();
}

public MyEnum getMyEnum(Context context) {
    SharedPreferences sp = context.getPreferences(this.MODE_PRIVATE);
    String myEnumString = sp.getString("MyEnum", MyEnum.ENUM1.toString());
    return MyEnum.toMyEnum(myEnumString);
}

以下是示例代码,您可以看到它是如何工作的。 https://github.com/jiahaoliuliu/SavingEnumToSharedPreferences

答案 1 :(得分:34)

这与Enterprise Java开发人员在将枚举持久保存到数据库时面临的问题相同。现有答案的问题在于它们是脆弱的而不是重构友好的。这就是为什么(在底部有另一种选择。)

使用枚举toString()valueOf()方法意味着无法重命名枚举值。假设我的VehicleType枚举值为CARTRUCK。如果我存储字符串" TRUCK"作为偏好值,然后在我的应用的下一个版本中将VehicleType.TRUCK重命名为VehicleType.PICKUP_TRUCK,存储的字符串不再有意义,valueOf()将抛出IllegalArgumentException

使用值的序数意味着无法重新排序枚举值,或者您的存储值将不再匹配。这种情况可能会更糟,因为您的应用程序将继续运行,但可能会以意想不到的方式运行,一旦它最终被注意到并且可能无法纠正,就很难找到问题。在除了结尾之外的任何地方添加新值也是如此。如果我在顶部添加了新的MOTORCYCLE值,则在应用的先前版本中存储为序号(0)的CAR将在更新后返回MOTORCYCLE,并且{ {1}}(序号1)将成为TRUCK

我使用的替代方法是在枚举中添加CAR字段并使用其值,如下所示:

final

使用public enum VehicleType { CAR("C"), TRUCK("T"); private final String code; private static final Map<String,VehicleType> valuesByCode; static { valuesByCode = new HashMap<>(values().length); for(VehicleType value : values()) { valuesByCode.put(value.code, value); } } VehicleType(String code) { this.code = code; } public static VehicleType lookupByCode(String code) { return valuesByCode.get(code); } public String getCode() { return code; } } 之类的内容存储值,并使用preferences.putString("vehicle_type", vehicleType.getCode())等内容检索。

这种方法需要一些额外的代码,但在我看来,它是最强大的解决方案。

答案 2 :(得分:11)

你可以用整数来表示你的枚举并存储简单的int,看看:

Cast Int to enum in Java(第二个答案) - 同样可以enumToInt

答案 3 :(得分:2)

考虑到上述所有选项,我决定使用另一种方案解决问题。

我只需要一组值,而不需要任何逻辑。在这种情况下,可以使用@StringDefenum等工具,而不是@IntDef

根据变量名称和变量顺序,解决方案是安全的。唯一不应该改变的是 - 实际值。但是,默认重构工具不会要求您在重命名的情况下更改它们,因此要自动制作它并不是那么容易(@StringDef从这个角度来看比 @Retention(SOURCE) @IntDef({NOT_REQUESTED, GIVEN, PROHIBITED}) public @interface CustomPermission {} public static final int NOT_REQUESTED = -1; public static final int PROHIBITED = 0; public static final int GIVEN = 1; @CustomPermission public int getPermission() { return getSharedPreferences(SHARED_PREFS_FILE) .getInt(STATISTICS_COLLECTION_PERMISSION, NOT_REQUESTED); } public void setPermission(@CustomPermission int flag) { getSharedPreferences(SHARED_PREFS_FILE) .edit() .putInt(STATISTICS_COLLECTION_PERMISSION, flag) .apply(); } 更好})。

| rex field=message ">\s+(?<httpmethod>\w*).*/selfservice"

这是official doc

答案 4 :(得分:0)

这是我为此编写的一个不错的utils类。它非常通用,可以满足各种各样的要求。

import android.content.Context;
import android.content.SharedPreferences;

public class PreferencesUtils
{
    enum StorageMode {
        /** Store enum by ordinal. */
        ORDINAL,

        /** Store enum by name. */
        NAME
    }

    private static final String PREFERENCES_NAME = "your_prefs_name";

    /**
     * Put an enum in SharedPreferences with the given key.
     * @param context The context
     * @param key The preference key
     * @param enumm The enum to store
     * @param mode The mode to store the enum - by name or ordinal
     */
    public static void putEnum(final Context context, final String key, final Enum enumm, final StorageMode mode)
    {
        final SharedPreferences sp = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
        final SharedPreferences.Editor editor = sp.edit();
        switch (mode)
        {
            default:
            case ORDINAL:
                editor.putInt(key, enumm.ordinal());
                break;
            case NAME:
                editor.putString(key, enumm.name());
                break;
        }
        editor.apply();
    }

    /**
     * Get the enum stored in SharedPreferences with the given key.
     * @param context The context
     * @param key The preference key
     * @param enumType The type of Enum stored
     * @param defaultEnumm Enum returned if a preference stored with key does not exist. Can be null.
     * @param mode The mode by which the enum was originally stored
     * @param <T> The type of Enum stored
     * @return The Enum stored as a preference with the given key
     */
    public static <T extends Enum<T>> Enum getEnum(final Context context, final String key, final Class<T> enumType,
                                                   final Enum defaultEnumm, final StorageMode mode)
    {
        final SharedPreferences sp = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
        final T[] values = enumType.getEnumConstants();

        switch (mode)
        {
            default:
            case ORDINAL:
                final int ord = sp.getInt(key, -1);
                return ord == -1 ? defaultEnumm : values[ord];
            case NAME:
                final String name = sp.getString(key, null);
                for (final T value : values)
                {
                    if (value.name().equals(name))
                    {
                        return value;
                    }
                }
        }
        return defaultEnumm;
    }
}