我想知道,用于将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);
我在想,这是一个好方法吗?还有更好的办法吗?
答案 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
枚举值为CAR
和TRUCK
。如果我存储字符串" 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)
考虑到上述所有选项,我决定使用另一种方案解决问题。
我只需要一组值,而不需要任何逻辑。在这种情况下,可以使用@StringDef
和enum
等工具,而不是@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"
答案 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;
}
}