如何使用SharedPreferences保存多个值?

时间:2012-01-29 15:10:43

标签: android database sharedpreferences

我正在开发一个字典应用程序。在我的应用程序中,我假设用户想要保存喜欢的单词。我决定使用 SharedPreferences 来保存这些值(我知道SQLite和文件更好,但我坚持使用“SharedPreferences”,所以请继续使用它。)

以下是我的代码:

@Override
public void onClick(View v) {                                       
    SharedPreferences faves = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    { 
        SharedPreferences.Editor editor = faves.edit();
        editor.putString("favourite", mSelectedDB + "::" + mCurrentWordId + "::" + mCurrentWord + ",");
        editor.commit();    
    }
    Log.i(CONTENT_TAG,"Favourite saved!");

    Toast toast = Toast.makeText(ContentView.this, R.string.messageWordAddedToFarvourite, Toast.LENGTH_SHORT);
    toast.show();   
}

问题在于它不会保留多个喜欢的单词。我的意思是只保存了一个喜欢的单词,当添加一个新单词时,前一个单词将被删除。

那么,如何编辑上述代码以解决此问题?

你们有帮助吗?非常感谢你。

6 个答案:

答案 0 :(得分:19)

您可以在单个首选项中保存多个收藏夹,方法是在一个字符串中添加多个收藏夹,每个收藏夹项目用逗号分隔。然后,您可以使用convertStringToArray方法将其转换为String Array。这是完整的源代码 使用MyUtility Methods保存多个喜欢的项目。

            MyUtility.addFavoriteItem(this, "Sports");
            MyUtility.addFavoriteItem(this, "Entertainment");

获取所有收藏夹保存的字符串数组

String[] favorites = MyUtility.getFavoriteList(this);// returns {"Sports","Entertainment"};

将这些方法保存在单独的Utility类中

 public abstract class MyUtility {

    public static boolean addFavoriteItem(Activity activity,String favoriteItem){
        //Get previous favorite items
        String favoriteList = getStringFromPreferences(activity,null,"favorites");
        // Append new Favorite item
        if(favoriteList!=null){
            favoriteList = favoriteList+","+favoriteItem;
        }else{
            favoriteList = favoriteItem;
        }
        // Save in Shared Preferences
        return putStringInPreferences(activity,favoriteList,"favorites");
    }
    public static String[] getFavoriteList(Activity activity){
        String favoriteList = getStringFromPreferences(activity,null,"favorites");
        return convertStringToArray(favoriteList);
    }
    private static boolean putStringInPreferences(Activity activity,String nick,String key){
        SharedPreferences sharedPreferences = activity.getPreferences(Activity.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(key, nick);
        editor.commit();                        
        return true;        
    }
    private static String getStringFromPreferences(Activity activity,String defaultValue,String key){
        SharedPreferences sharedPreferences = activity.getPreferences(Activity.MODE_PRIVATE);
        String temp = sharedPreferences.getString(key, defaultValue);
        return temp;        
    }

    private static String[] convertStringToArray(String str){
        String[] arr = str.split(",");
        return arr;
    }
}

如果您必须添加额外收藏。然后从SharedPreference获取最喜欢的字符串并附加逗号+收藏项并将其保存回SharedPreference
*您可以使用任何其他字符串作为分隔符而不是逗号。

答案 1 :(得分:7)

SharedPreferences通过简单的键/值工作,因此当您为同一个键提供新值时,将覆盖之前的值。做你想要做的事情的唯一方法就是使用不同的键,这些暗示你可能不应该使用SharedPreferences来做你正在尝试做的事情。

答案 2 :(得分:5)

Honeycomb添加了putStringSet方法,所以你可以使用它,如果你不需要支持少于Honeycomb的东西:

@Override
public void onClick(View v) {
    SharedPreferences faves = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    {
        Set<String> faveSet = faves.getStringSet("favourite");
        faveSet.add(mSelectedDB + "::" + mCurrentWordId + "::" + mCurrentWord + ",");
        SharedPreferences.Editor editor = faves.edit();
        editor.putStringSet("favourite", faveSet);
        editor.commit();
    }
    Log.i(CONTENT_TAG,"Favourite saved!");

    Toast toast = Toast.makeText(ContentView.this, R.string.messageWordAddedToFarvourite, Toast.LENGTH_SHORT);
    toast.show();
}

如果您需要支持预蜂窝设备,您必须提出自己的方案。

一种可能性是将单词作为逗号分隔值存储在一个首选项中。

另一种方法是为每个新单词生成一个新密钥,“favourite1”,“favourite2”,“favourite3”,并使用另一个偏好来存储单词数。

答案 3 :(得分:2)

每次单击按钮时,都会使用已存在的密钥favorite保存最喜欢的单词并覆盖它。要保存多个单词,您必须使用不同的键保存单词。 因此,每次保存您喜欢的单词时,您都可以这样做:

private static int incrementedValue = 0;
...
@Override
public void onClick(View v) {
    SharedPreferences faves = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

    SharedPreferences.Editor editor = faves.edit();
    editor.putString("favourite" + incrementedValue, mSelectedDB + "::" + mCurrentWordId + "::" + mCurrentWord + ",");
    editor.commit();

    Log.i(CONTENT_TAG,"Favourite saved!");

    Toast toast = Toast.makeText(ContentView.this, R.string.messageWordAddedToFarvourite, Toast.LENGTH_SHORT);
    toast.show();
    incrementedValue++;
}

答案 4 :(得分:1)

那是因为实际的首选项存储不是一个字符串列表,只是一个字符串,所以每当你说putString()时你都会覆盖以前的值。在单个首选项字符串中存储多个对象的好方法是使用JSON。只需序列化该值,然后将其写入它们。它还具有直接转换回您希望的任何复杂对象的好处。如果你决定继续这条路线,请考虑使用Jackson

答案 5 :(得分:1)

您可以使用TreeMap(或实现Serializable的其他类型的列表)。这是我最近处理收藏列表的方式。在TreeMap中,Favorite是我使用的类。在您的情况下,您可以使用TreeMap&lt; Integer,String&gt;代替。

private static TreeMap<Integer, Favourite> favourites;

...
...
...

// load favourites
FileInputStream fis=null;
ObjectInputStream ois = null;
try {
    fis = context.openFileInput(context.getString(R.string.favourites_file));
    try {
    ois = new ObjectInputStream(fis);
    favourites = (TreeMap<Integer, Favourite>) ois.readObject();
    } catch (StreamCorruptedException e) {
    } catch (IOException e) {
    } catch (ClassNotFoundException e) {
    }
} catch (FileNotFoundException e) {
} finally {
    try {
    if (ois!=null){
        ois.close();
    }
    } catch (IOException e) {
    }    
}

if (favourites==null){
    favourites = new TreeMap<Integer, Favourite>();     
}

...
...
...

// save favourites
FileOutputStream fos=null;
ObjectOutputStream oos=null;
try {
    fos = context.openFileOutput(context.getString(R.string.favourites_file), MODE_PRIVATE);
    try {
    oos = new ObjectOutputStream(fos);
    oos.writeObject(favourites);
    } catch (IOException e) {
    }
} catch (FileNotFoundException e) {
} finally {
    if (oos!=null){
    try {
        oos.close();
    } catch (Exception e2) {

    }
    }    
}

您还可以避免使用“::”来分隔值。

希望有帮助...