2016-07-19 3 views
1

Я работаю над созданием класса утилиты для хранения данных в SharedPreferences. До сих пор я смог создать общую функцию для хранения и извлечения String, int и boolean. Существует ли общий способ хранения и извлечения коллекции объектов?Хранить коллекцию объектов в SharedPreferences

+0

Не могли бы вы предоставить вам общую функцию? –

+0

Подсказка: как насчет хранения JSON непосредственно как String ... !!! –

+0

с помощью TinyDB вы можете хранить универсальные объекты любого типа https://github.com/kcochibili/TinyDB--Android-Shared-Preferences-Turbo –

ответ

0

Существует ли общий способ хранения и извлечения коллекции объектов?

Нет, на данный момент нет общего способа. Вы можете использовать следующие методы:

  • putBoolean (ключ String, логическое значение)

  • putFloat (ключ String, значение с плавающей точкой)

  • putInt (ключ String, INT значение)

  • putLong (ключ String, долгое значение)

  • putString (ключ String, значение String)

  • putStringSet (ключ String, установленные значения)

Это все, что вы можете сделать с SharedPreferences. Если вы хотите сохранить что-либо общее, вы можете попробовать сериализовать свой объект и поместить его как String в SharedPreferences. About Serialization

0

Я проводил много времени, играя с этим вопросом. Поскольку я работаю с парнем iPhone, как можно сохранить anyObjects (что это такое?) :)

Я решил использовать 2 решения. Если я храню кеш, который имеет кратковременное использование, я обертываю произвольный объект в виде Parceable с Parceler (https://github.com/johncarl81/parceler).

Если мне нужны постоянные данные, которые приложение использует для сохранения действий пользователя, я переношу любой объект с GSON и сохраняю его на диск. Таким образом, я все еще могу обновить приложение с большим количеством полей и по-прежнему использовать данные, которые поступают от объекта GSON, поскольку он обрабатывает поля нулевого значения. (https://github.com/google/gson)

2

Там нет прямого пути, но два косвенных способов:

1. Используйте GSON.

public static boolean saveObjectToPrefs(String prefKey, Object object, Context context) { 
    SharedPreferences.Editor editor = getSharedPreferences(context).edit(); 
    try { 
     Gson gson = new Gson(); 
     String json = gson.toJson(object); 
     editor.putString(prefKey, json); 
     editor.apply(); 
     return true; 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return false; 
    } 
} 

Родовое здесь следует осуществлять Serializable интерфейс.

Чтобы получить объект создать метод, как это:

public static <T> T getObjectFromPrefs(String prefKey, Class<T> type, Context context) { 
    String json = getSharedPreferences(context).getString(prefKey, null); 
    if (json != null) { 
     try { 
      Gson gson = new Gson(); 
      T result = gson.fromJson(json, type); 
      return result; 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
    return null; 
} 

и вы можете вызвать этот метод, как для коллекций:

PrefUtils.getObjectFromPrefsByType(PREF_KEY_USERS, new TypeToken<ArrayList<User>>() { 
    }.getType(), context); 

для обычных объектов, которые вы можете сделать:

PrefUtils.getObjectFromPrefsByType(PREF_KEY_USER, User.class, context); 

2. Напишите пользовательский Сериализатор и Deserializer

Обычно я предпочитаю этот метод, так как мне не нужно включать в него библиотеку.

Вот обычай сериализатору/десериализатор реализация:

public class ObjectSerializer { 


public static String serialize(Serializable obj){ 
    if (obj == null) return ""; 
    try { 
     ByteArrayOutputStream serialObj = new ByteArrayOutputStream(); 
     ObjectOutputStream objStream = new ObjectOutputStream(serialObj); 
     objStream.writeObject(obj); 
     objStream.close(); 
     return encodeBytes(serialObj.toByteArray()); 

    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 

} 

public static Object deserialize(String str) { 
    if (str == null || str.length() == 0) return null; 
    try { 
     ByteArrayInputStream serialObj = new ByteArrayInputStream(decodeBytes(str)); 
     ObjectInputStream objStream = new ObjectInputStream(serialObj); 
     return objStream.readObject(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 

public static String encodeBytes(byte[] bytes) { 
    StringBuilder strBuf = new StringBuilder(); 
    for (Byte b: bytes) { 
     strBuf.append((char) (((b >> 4) & 0xF) + ((int) 'a'))); 
     strBuf.append((char) (((b) & 0xF) + ((int) 'a'))); 
    } 
    return strBuf.toString(); 
} 

public static byte[] decodeBytes(String str) { 
    byte[] bytes = new byte[str.length()/2]; 
    for (int i = 0; i < str.length(); i+=2) { 
     char c = str.charAt(i); 
     bytes[i/2] = (byte) ((c - 'a') << 4); 
     c = str.charAt(i+1); 
     bytes[i/2] += (c - 'a'); 
    } 
    return bytes; 
    } 
} 

Теперь внутри PrefUtils.java вы можете иметь метод, как:

public static void saveUser(Context context, User user) { 
    getSharedPreferences(context) 
         .edit() 
         .putString(PREF_KEY_USER, ObjectSerializer.serialize(user)) 
         .apply(); 
} 

Чтобы получить объект, который вы можете использовать следующий метод:

public static User getUser(Context context) { 
    String serializedUser = getSharedPreferences(context).getString(PREF_KEY_USER, ""); 
    return ((User) ObjectSerializer.deserialize(serializedUser)); 
} 

Снова Пользовательский класс должен быть Serializable. Кроме того, не забывайте явное литье, поскольку метод ObjectSerializer.deserialize (String str) возвращает объект типа Объект, а не класс, который вы сериализовали. Кроме того, позаботьтесь о нулевых значениях.

+0

Как мы можем использовать этот общий для хранения и получить список объектов @Embydextrous –

+0

Вы говорите о методе GSON: Чтобы сохранить позвонить: PrefUtils.saveObjectToPrefs (PREF_KEY_USERS, пользователи, контекст); // пользователи - ArrayList , и пользователь сериализуется. – Embydextrous

+0

Чтобы получить звонок: PrefUtils.getObjectFromPrefsByType (PREF_KEY_USER, новый TypeToken >() { } .getType(), контекст); – Embydextrous

Смежные вопросы