【问题标题】:How to use SharedPreferences to save more than one values?如何使用 SharedPreferences 保存多个值?
【发布时间】:2012-02-21 16:13:12
【问题描述】:

我正在开发一个字典应用程序。在我的应用程序中,我假设用户想要保存最喜欢的单词。我决定使用 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();   
}

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

那么,如何编辑上面的代码来解决这个问题呢?

你们能帮忙吗?非常感谢。

【问题讨论】:

    标签: android database sharedpreferences


    【解决方案1】:

    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”,并使用另一个首选项来存储单词的数量。

    【讨论】:

    • 确实如此,但不幸的是,我正在为前蜂窝设备做事。非常感谢。
    【解决方案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++;
    }
    

    【讨论】:

    • 非常感谢。我喜欢你的方法,但是当它被应用时,它会产生 incrementedValue 的错误,说 VariableDeclarationId expected after...
    • @user998032 我编辑了我的答案,我忘记将int 添加到 incrementedValue 变量的声明中(不要忘记在你的类中添加第一行,变量声明,使用方法onClick()).
    • 非常感谢,笨蛋!它有效,但不像我预期的那样。 SharePreferences 现在将字符串保存为:&lt;string name="favourite4"&gt;dict_name::157562::heap up,&lt;/string&gt; &lt;string name="favourite3"&gt;dict_name::31377::bell,&lt;/string&gt; &lt;string name="favourite2"&gt;dict_name::349333::tell,&lt;/string&gt; &lt;string name="favourite1"&gt;dict_name::349333::tell,&lt;/string&gt; &lt;string name="favourite0"&gt;dict_name::11834::am,&lt;/string&gt;,但仅加载第一个最喜欢的单词(“favourite0”)以供查看。
    【解决方案3】:

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

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

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

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

    将这些方法保存在单独的实用程序类中

     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
    * 您可以使用任何其他字符串作为分隔符,而不是逗号。

    【讨论】:

    • 非常感谢。但我还不明白要以编程方式做什么。这是 SharedPreferences 的字符串形式:&lt;string name="favourite"&gt;dict_name::149272::go,&lt;/string&gt;。你的代码应该放在哪里?
    • @user998032 我添加了代码来解释我们如何添加多个收藏项。您可以按原样使用代码,它会为您工作。
    • @@Muhammad Nabeel Arif:非常感谢,但还是没有运气,对不起!我希望在 onClick 之后保存收藏夹,但是在上面编辑的代码之后产生了许多错误。
    • @user998032 我在我的应用程序中使用相同的代码来维护已成功登录应用程序的用户的历史记录。它在我这边工作得很好。请告诉我您面临的具体错误。也许我可以帮助你。
    • 非常感谢。我真的不知道为什么,但是在 onClick 之后放置时...它显示 语法错误。您现在可以加入聊天室吗?
    【解决方案4】:

    您可以使用 TreeMap(或其他类型的实现 Serializable 的列表)。这是我最近处理收藏夹列表的方式。在 TreeMap 中,Favorite 是我使用的一个类。在您的情况下,您可以只使用 TreeMap

    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) {
    
        }
        }    
    }
    

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

    希望对您有所帮助...

    【讨论】:

    • 非常感谢。我以前尝试过类似的方法,但是在列出收藏夹时遇到了问题。
    【解决方案5】:

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-20
        • 1970-01-01
        • 1970-01-01
        • 2020-09-13
        相关资源
        最近更新 更多