无法控制共享偏好设置中设置的字符串顺序



这是我的第一个堆栈溢出问题。我已经对此做了很多谷歌搜索。 在 Hashsets、Treesets、LinkedHashSets、Collections、Stacks 上(Stack class 已被弃用?)...我意识到我可以只使用 SQLite,但我暂时试图避免这种情况。

我正在 Android Studio 中开发一个应用程序。该应用程序与人打交道,列出他们并以不同的方式与他们联系。应用用户可以维护和控制三种类型的列表:最近联系、阻止和收藏夹。 这些列表在共享首选项中存储为字符串集,以便在应用程序关闭和重新打开后继续存在。 使用联机数据库填充列表时,各个字符串充当主键。 我最关心的是"最近联系"列表,因为此列表的顺序很重要。

问题是,据我了解,当我声明一个字符串集时,它如下所示:

Set<String> faveArray = new LinkedHashSet<String>;

据我了解,我只能在右侧使用HashSet,LinkedHashSet或TreeSet。

由于我使用了 LinkedHashset,我预计当我重新打开应用程序并将数据从共享首选项中提取出来时,字符串将从最近添加的字符串(LIFO/stack)开始拉出,因此当我填充列表视图时,它们将显示在列表顶部的"最近联系"人员,依此类推......或者至少我希望有某种可以预测的顺序/行为,我可以使用它。

所以。。。。。。。我已经为我的共享首选项 I/O 类附加了我的代码。

从我的主应用程序中,我执行以下操作:

static SharedPrefUTIL sharedPrefUTIL;
sharedPrefUTIL = new SharedPrefUTIL(this);
sharedPrefUTIL.addRecent("derp");
sharedPrefUTIL.addRecent("nerp");
sharedPrefUTIL.addRecent("gerp");
sharedPrefUTIL.addRecent("herp");

此时,代码

Log.i(TAG, set + " committed to " + key);

在类 SharedPrefUTIL 日志的 commit() 方法中:

" [derp, nerp, gerp, herp] 致力于 recentArray "

但是在关闭并重新打开应用程序后,如果我们执行以下操作:

sharedPrefUTIL.toastContents("R");

结果似乎是随机顺序。 <<<<这是我的问题。

任何帮助非常感谢。

package com.secretsoft.booberbunz;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import android.widget.Toast;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Queue;
import java.util.Set;
import java.util.TreeSet;
/**
* Created by Programming on 2/22/2016.
*/
public class SharedPrefUTIL {
protected static final String TAG = "CXX SharedPrefUTIL";
Context context;
SharedPreferences sharedPreferences;
Set<String> faveArray;
Set<String> blockArray;
Set<String> recentArray;
public static final Set<String> DEFAULT = new HashSet<String>(Arrays.asList("empty"));

public SharedPrefUTIL(Context context){
    this.context = context;
    // load shared prefs into static arrays (new objects to prevent problems)
    sharedPreferences = context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
    recentArray = new LinkedHashSet<String>(sharedPreferences.getStringSet("recentArray",DEFAULT));
    blockArray = new LinkedHashSet<String>(sharedPreferences.getStringSet("blockArray",DEFAULT));
    faveArray = new LinkedHashSet<String>(sharedPreferences.getStringSet("faveArray",DEFAULT));
    Log.i(TAG, "SharedPrefUTIL instance created");

    if (recentArray.contains("empty")) {
        recentArray.clear();
        Log.i(TAG, "recentArray contains the string -empty- and was cleared");
    }
    if (blockArray.contains("empty")) {
        blockArray.clear();
        Log.i(TAG, "blockArray contains the string -empty- and was cleared");
    }
    if (faveArray.contains("empty")) {
        faveArray.clear();
        Log.i(TAG, "faveArray contains the string -empty- and was cleared");
    }
}
public void toastLength(String type){
    if (type == "R"){
        String temp = type + " array is this long: " + recentArray.size();
        Toast.makeText(context, temp,
                Toast.LENGTH_LONG).show();
        Log.i(TAG, temp);

    }
    else if (type == "B"){
        String temp = type + " array is this long: " + blockArray.size();
        Toast.makeText(context, temp,
                Toast.LENGTH_LONG).show();
        Log.i(TAG, temp);
    }
    else if (type == "F"){
        String temp = type + " array is this long: " + faveArray.size();
        Toast.makeText(context, temp,
                Toast.LENGTH_LONG).show();
        Log.i(TAG, temp);
    }
    else {
        Log.i(TAG, "invalid type param given to toastLength()");
    }
}

public void toastContents(String type){
    if (type == "R"){
        for (String temp : recentArray) {
        Toast.makeText(context, temp,
                Toast.LENGTH_LONG).show();
        Log.i(TAG, "recentArray contains: " + temp);
    }
    }
    else if (type == "B"){
        for (String temp : blockArray) {
            Toast.makeText(context, temp,
                    Toast.LENGTH_LONG).show();
            Log.i(TAG, "blockArray contains: " + temp);
        }
    }
    else if (type == "F"){
        for (String temp : faveArray) {
            Toast.makeText(context, temp,
                    Toast.LENGTH_LONG).show();
            Log.i(TAG, "faveArray contains: " + temp);
        }
    }
    else {
        Log.i(TAG, "invalid type param given to toastContents()");
    }

}
public void clearList(String type){
    if (type == "R"){
        recentArray.clear();
        commit("recentArray", recentArray);
        Toast.makeText(context,"recent list has been cleared.", Toast.LENGTH_LONG);
    }
    else if (type == "B"){
        blockArray.clear();
        commit("blockArray", blockArray);
        Toast.makeText(context,"blacklist has been cleared.", Toast.LENGTH_LONG);
    }
    else if (type == "F"){
        faveArray.clear();
        commit("faveArray", faveArray);
        Toast.makeText(context,"favorites have been cleared.", Toast.LENGTH_LONG);
    }
    else {
        Log.i(TAG, "invalid type param given to clearList()");
    }
}
public void addRecent(String newRecent){
    recentArray.add(newRecent);
    commit("recentArray", recentArray);
    Log.i(TAG, newRecent + " added to recentArray");
}
public void addBlocked(String newBlocked, String  nick){
    blockArray.add(newBlocked);
    commit("blockArray", blockArray);
    Toast.makeText(context, nick + " has been blacklisted!", Toast.LENGTH_SHORT);
}
public void remBlocked(String remBlocked, String nick){
    blockArray.remove(remBlocked);
    commit("blockArray", blockArray);
    Toast.makeText(context, nick + " has been unblocked.", Toast.LENGTH_SHORT);
}
public void addFave(String newFave, String nick){
    faveArray.add(newFave);
    commit("faveArray", faveArray);
    Toast.makeText(context, nick + " added to favorites!", Toast.LENGTH_SHORT);
}
public void remFave(String remFave, String nick){
    faveArray.remove(remFave);
    commit("faveArray", faveArray);
    Toast.makeText(context, nick + " removed from favorites.", Toast.LENGTH_SHORT);
}
public void commit(String key, Set<String> set){
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putStringSet(key,set);
    editor.commit();
    Log.i(TAG, set + " committed to " + key);
}


}

不幸,但你只是发现了SharedPreferences的限制。

当您使用有序哈希时,当您调用 getStringSet 时,它不会加载有序哈希。

我发现这样做的最快最简单的方法是将数组转换为文本,有序,然后将其保存到共享首选项中。 Android附带了一个可以做到这一点的对象JSONArray

http://developer.android.com/reference/org/json/JSONArray.html

这里有一些伪代码可以做你想要的:

public void saveOrderedCollection(Collection collection, String key){
    JSONArray jsonArray = new JSONArray(collection);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString(key, jsonArray.toString());
    editor.commit();
}
public Collection loadOrderedCollection(String key){
    ArrayList arrayList = new ArrayList;
    SharedPreferences.Editor editor = sharedPreferences.edit();
    JSONArray jsonArray = new JSONArray(editor.getString(key, "[]"));
    for (int i = 0; i < jsonArray.length(); i++) {
        arrayList.put(jsonArray.get(i));
    }
    return arrayList;
}

以下是我用来制作的其他一些帖子:

是否可以将数组或对象添加到Android上的共享首选项

在共享首选项中,如何在Android应用程序中存储字符串数组

使用 kotlin,您可以简单地编写扩展函数来存储字符串列表,该列表在您添加它们时保持顺序:

   fun SharedPreferences.Editor.putStringList(key: String, list: List<String>) {
        this.putString(key, list.joinToString(";"))
    }
   fun SharedPreferences.getStringList(key: String): List<String> {
        return this.getString(key, "")?.split(";") ?: listOf()
    }

然后,您可以像这样存储您的值:

sharedPrefs.edit().putStringList("SOME_KEY", listOf("A", "B", "C"))

并像这样接收它们:

val myList = sharedPrefs.getStringList("SOME_KEY")

我已经实现了建议的更改(在保存到共享首选项时使用 JSON 字符串而不是字符串集),这是我的共享 pref 类的新代码,以防其他人尝试做同样的事情。 故障排除日志可能矫枉过正,但这就是我滚动的方式,因为我不知道如何正确调试。

package [];
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * Created by Programming on 2/22/2016.
 */
public class SharedPrefUTIL {
protected static final String TAG = "CXX SharedPrefUTIL";
Context context;
SharedPreferences sharedPreferences;
Set<String> recentArray;
Set<String> blockArray;
Set<String> faveArray;
JSONArray recentJArray;
JSONArray blockJArray;
JSONArray faveJArray;

public SharedPrefUTIL(Context context){
    this.context = context;
    // START load arrays from shared prefs
    sharedPreferences = context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
    try {
        recentJArray = new JSONArray(sharedPreferences.getString("recentArray","[]"));
        blockJArray = new JSONArray(sharedPreferences.getString("blockArray","[]"));
        faveJArray = new JSONArray(sharedPreferences.getString("faveArray","[]"));
    } catch (JSONException e) {
        e.printStackTrace();
        Log.i(TAG, e.toString());
    }
    Log.i(TAG, "length of recentJArray is " + recentJArray.length());
    recentArray = new LinkedHashSet<String>();
    blockArray = new LinkedHashSet<String>();
    faveArray = new LinkedHashSet<String>();
    for (int i = 0; i < recentJArray.length(); i++) {
        try {
            recentArray.add(recentJArray.getString(i));
        } catch (JSONException e) {
            e.printStackTrace();
            Log.i(TAG, e.toString());
        }
    }
    for (int i = 0; i < blockJArray.length(); i++) {
        try {
            blockArray.add(blockJArray.getString(i));
        } catch (JSONException e) {
            e.printStackTrace();
            Log.i(TAG, e.toString());
        }
    }
    for (int i = 0; i < faveJArray.length(); i++) {
        try {
            faveArray.add(faveJArray.getString(i));
        } catch (JSONException e) {
            e.printStackTrace();
            Log.i(TAG, e.toString());
        }
    }
    // END load arrays from shared prefs
    Log.i(TAG, "SharedPrefUTIL instance created");
}
public void toastLength(String type){
    if (type == "R"){
        String temp = type + " array is this long: " + recentArray.size();
        Toast.makeText(context, temp,
                Toast.LENGTH_LONG).show();
        Log.i(TAG, temp);

    }
    else if (type == "B"){
        String temp = type + " array is this long: " + blockArray.size();
        Toast.makeText(context, temp,
                Toast.LENGTH_LONG).show();
        Log.i(TAG, temp);
    }
    else if (type == "F"){
        String temp = type + " array is this long: " + faveArray.size();
        Toast.makeText(context, temp,
                Toast.LENGTH_LONG).show();
        Log.i(TAG, temp);
    }
    else {
        Log.i(TAG, "invalid type param given to toastLength()");
    }
}

public void toastContents(String type){
    if (type == "R"){
        for (String temp : recentArray) {
            Toast.makeText(context, temp, Toast.LENGTH_LONG).show();
            Log.i(TAG, "recentArray contains: " + temp);
        }
    }
    else if (type == "B"){
        for (String temp : blockArray) {
            Toast.makeText(context, temp,
                    Toast.LENGTH_LONG).show();
            Log.i(TAG, "blockArray contains: " + temp);
        }
    }
    else if (type == "F"){
        for (String temp : faveArray) {
            Toast.makeText(context, temp,
                    Toast.LENGTH_LONG).show();
            Log.i(TAG, "faveArray contains: " + temp);
        }
    }
    else {
        Log.i(TAG, "invalid type param given to toastContents()");
    }

}
public void clearList(String type){
    if (type == "R"){
        recentArray.clear();
        commit("recentArray", recentArray);
        Toast.makeText(context,"recent list has been cleared.", Toast.LENGTH_LONG);
    }
    else if (type == "B"){
        blockArray.clear();
        commit("blockArray", blockArray);
        Toast.makeText(context,"blacklist has been cleared.", Toast.LENGTH_LONG);
    }
    else if (type == "F"){
        faveArray.clear();
        commit("faveArray", faveArray);
        Toast.makeText(context,"favorites have been cleared.", Toast.LENGTH_LONG);
    }
    else {
        Log.i(TAG, "invalid type param given to clearList()");
    }
}
public void addRecent(String newRecent){
    recentArray.add(newRecent);
    commit("recentArray", recentArray);
    Log.i(TAG, newRecent + " added to recentArray");
}
public void addBlocked(String newBlocked){
    blockArray.add(newBlocked);
    commit("blockArray", blockArray);
    Toast.makeText(context, newBlocked + " has been blacklisted!", Toast.LENGTH_SHORT);
}
public void remBlocked(String remBlocked){
    blockArray.remove(remBlocked);
    commit("blockArray", blockArray);
    Toast.makeText(context, remBlocked + " has been unblocked.", Toast.LENGTH_SHORT);
}
public void addFave(String newFave){
    faveArray.add(newFave);
    commit("faveArray", faveArray);
    Toast.makeText(context, newFave + " added to favorites!", Toast.LENGTH_SHORT);
}
public void remFave(String remFave){
    faveArray.remove(remFave);
    commit("faveArray", faveArray);
    Toast.makeText(context, remFave + " removed from favorites.", Toast.LENGTH_SHORT);
}
public void commit(String key, Set<String> set){
    // convert set into JSON
    JSONArray jsonArray = new JSONArray(set);
    Log.i(TAG, "During commit, jsonArray(set) is this long: " + jsonArray.length());
    //-------------------------------------------

    // commit changes
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString(key,jsonArray.toString());
    editor.commit();
    Log.i(TAG, jsonArray.toString() + " committed to " + key);
}
}

相关内容

  • 没有找到相关文章

最新更新