如何将List<Object>保存到SharedPreferences?

45

我有一个产品列表,从web服务检索到。当应用程序首次打开时,应用程序会从web服务获取产品列表。我想将此列表保存到共享偏好中。

    List<Product> medicineList = new ArrayList<Product>();

Product类定义如下:

public class Product {
    public final String productName;
    public final String price;
    public final String content;
    public final String imageUrl;

    public Product(String productName, String price, String content, String imageUrl) {
        this.productName = productName;
        this.price = price;
        this.content = content;
        this.imageUrl = imageUrl;
    }
}

我该如何保存这个List,而不需要每次都从Web服务请求?


2
你只能将基本数据类型的值保存到SharedPrefrences中。 - Murtaza Khursheed Hussain
11个回答

62

只能使用原始类型,因为偏好保持在内存中。但是您可以使用Gson将类型序列化为JSON并将字符串放入偏好中:

private static SharedPreferences sharedPreferences = context.getSharedPreferences(STORE_FILE_NAME, Context.MODE_PRIVATE);

private static SharedPreferences.Editor editor = sharedPreferences.edit();
    
public <T> void setList(String key, List<T> list) {
    Gson gson = new Gson();
    String json = gson.toJson(list);
    
    set(key, json);
}

public static void set(String key, String value) {
    editor.putString(key, value);
    editor.commit();
}

以下为 @StevenTB 的评论中的额外信息:

检索(Retrive)

 public List<YourModel> getList(){
    List<YourModel> arrayItems;
    String serializedObject = sharedPreferences.getString(KEY_PREFS, null); 
    if (serializedObject != null) {
         Gson gson = new Gson();
         Type type = new TypeToken<List<YourModel>>(){}.getType();
         arrayItems = gson.fromJson(serializedObject, type);
     }
}

嘿,我知道现在已经很晚了,但是你为什么要使用静态变量和方法呢? - albert kim
@albertkim 我认为是这样的,因为他不需要每次都创建新的SharedPreferences实例。他在某个地方保留了一个变量以供以后使用。 - Neon Warge
3
你有存储使用GSON后获取列表的代码吗? - Ali Obeid
5
要从序列化的源中检索列表,请执行以下操作:List arrayItems; String serializedObject = sharedPreferences.getString(KEY_PREFS, null); if (serializedObject != null){ Gson gson = new Gson(); Type type = new TypeToken>(){}.getType(); arrayItems = gson.fromJson(serializedObject, type); } - StevenTB
当您的实例是静态的时,您如何使用 context.getShar...?我猜想 context 也是静态的,但是将 context 用作静态的是否明智? - ansh sachdeva

23

您可以使用GSON将对象转换为JSON(.toJson),也可以将JSON转换为对象(.fromJson)。

  • 根据您的需要定义标签(例如):

    private static final String PREFS_TAG = "SharedPrefs";
    private static final String PRODUCT_TAG = "MyProduct";
    
  • 将你的sharedPreference存储到这些标签中

  • private List<Product> getDataFromSharedPreferences(){
        Gson gson = new Gson();
        List<Product> productFromShared = new ArrayList<>();
        SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(PREFS_TAG, Context.MODE_PRIVATE);
        String jsonPreferences = sharedPref.getString(PRODUCT_TAG, "");    
    
        Type type = new TypeToken<List<Product>>() {}.getType();
        productFromShared = gson.fromJson(jsonPreferences, type);
    
        return preferences;
    }
    
  • 设置您的 sharedPreferences

    private void setDataFromSharedPreferences(Product curProduct){
        Gson gson = new Gson();
        String jsonCurProduct = gson.toJson(curProduct);
    
        SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(PREFS_TAG, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPref.edit();
    
        editor.putString(PRODUCT_TAG, jsonCurProduct);
        editor.commit();
    }
    
  • 如果您想保存一个产品数组,请按照以下步骤进行操作:

  • private void addInJSONArray(Product productToAdd){
    
        Gson gson = new Gson();
        SharedPreferences sharedPref = getApplicationContext().getSharedPreferences(PREFS_TAG, Context.MODE_PRIVATE);
    
        String jsonSaved = sharedPref.getString(PRODUCT_TAG, "");
        String jsonNewproductToAdd = gson.toJson(productToAdd);
    
        JSONArray jsonArrayProduct= new JSONArray();
    
        try {
            if(jsonSaved.length()!=0){
                jsonArrayProduct = new JSONArray(jsonSaved);
            }
            jsonArrayProduct.put(new JSONObject(jsonNewproductToAdd));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    
        //SAVE NEW ARRAY
        SharedPreferences.Editor editor = sharedPref.edit();
        editor.putString(PRODUCT_TAG, jsonArrayProduct);
        editor.commit();
    }
    

2
从JSONArray检索Products数组的代码是什么? - Adina Marin
2
你不能像这样尝试使用以下代码将json直接放入SharedPreference中: editor.putString(PRODUCT_TAG, jsonArrayProduct);你需要先将其转换为字符串(可能需要使用代码中的Gson对象)。例如: gson.toJson(jsonArrayProduct) - O'Kamiye
在获取对象时,我得到了“预期BEGIN_ARRAY但实际上是BEGIN_OBJECT”,位于第1行第2列路径$。 - Martin De Simone

8
SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);

保存

Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(myObject);
prefsEditor.putString("MyObject", json);
prefsEditor.commit();

获取数据
Gson gson = new Gson();
String json = mPrefs.getString("MyObject", "");
MyObject obj = gson.fromJson(json, MyObject.class);

1
问题已经得到回答并被接受,为什么您要添加重复的答案? - kakajan

5

正如接受的答案中所说,我们可以保存对象列表,如下:

public <T> void setList(String key, List<T> list) {
        Gson gson = new Gson();
        String json = gson.toJson(list);
        set(key, json);
    }

    public void set(String key, String value) {
        if (setSharedPreferences != null) {
            SharedPreferences.Editor prefsEditor = setSharedPreferences.edit();
            prefsEditor.putString(key, value);
            prefsEditor.commit();
        }
    }

使用以下方式获取:

public List<Company> getCompaniesList(String key) {
    if (setSharedPreferences != null) {

        Gson gson = new Gson();
        List<Company> companyList;

        String string = setSharedPreferences.getString(key, null);
        Type type = new TypeToken<List<Company>>() {
        }.getType();
        companyList = gson.fromJson(string, type);
        return companyList;
    }
    return null;
}

3

你目前有两个选择
a) 使用SharedPreferences
b) 使用SQLite并在其中保存值。

如何执行
a) SharedPreferences
首先,将列表存储为Set,然后在从SharedPreferences中读取时将其转换回List。

Listtasks = new ArrayList<String>();
Set<String> tasksSet = new HashSet<String>(Listtasks);
PreferenceManager.getDefaultSharedPreferences(context)
    .edit()
    .putStringSet("tasks_set", tasksSet)
    .commit();

当您阅读时:

Set<String> tasksSet = PreferenceManager.getDefaultSharedPreferences(context)
    .getStringSet("tasks_set", new HashSet<String>());
List<String> tasksList = new ArrayList<String>(tasksSet);
b) SQLite 一个好的教程:http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/

3

对于我和你来说最好的解决方案:

private static SharedPreferences sharedPreferences = context.getSharedPreferences(STORE_FILE_NAME, Context.MODE_PRIVATE);
private  SharedPreferences.Editor editor = sharedPreferences.edit();
List<your object> list = new ArrayList<>();

保存:

editor.edit().putString("your key name", new Gson().toJson(list)).apply();

对于"get":

list = new Gson().fromJson(sharedPreferences.getString("your key name", null), new TypeToken<List<your object class name>>(){}.getType());

享受它!


2
所有与JSON相关的答案都是可以的,但请记住Java允许您序列化任何对象,只要您实现了java.io.Serializable接口。这样,您也可以将其保存为序列化对象到首选项中。以下是一个示例,用于存储到首选项:https://gist.github.com/walterpalladino/4f5509cbc8fc3ecf1497f05e37675111。希望这可以作为一种选择来帮助您。

1

在SharedPreferences中,您只能存储基本类型的数据。

作为一种可能的方法,您可以使用GSON将值以JSON格式存储到偏好设置中。

Gson gson = new Gson();
String json = gson.toJson(medicineList);

yourPrefereces.putString("listOfProducts", json);
yourPrefereces.commit();

1
您可以使用以下方法使用Gson进行操作:
  • 从Web服务下载List<Product>
  • 使用new Gson().toJson(medicineList, new TypeToken<List<Product>>(){}.getType())List转换为Json String
  • 像平常一样将转换后的字符串保存到SharePreferences

为了重建您的List,您需要使用Gson中可用的fromJson方法来恢复该过程。


0

在 Kotlin 中获取通用列表的完美函数

private fun <T : Serializable> getGenericList(
    sharedPreferences: SharedPreferences,
    key: String,
    clazz: KClass<T>
): List<T> {
    return sharedPreferences.let { prefs ->
        val data = prefs.getString(key, null)
        val type: Type = TypeToken.getParameterized(MutableList::class.java, clazz.java).type
        gson.fromJson(data, type) as MutableList<T>
    }
}

你可以调用这个函数
getGenericList.(sharedPrefObj, sharedpref_key, GenericClass::class)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接