我有一个ArrayList
具有名称和图标指针的对象,我想将其保存在中SharedPreferences
。我能怎么做?
注意:我不想使用数据库
Answers:
因此,从Data Storage上的android开发者网站:
用户首选项
共享首选项并非严格用于保存“用户首选项”,例如用户选择的铃声。如果您有兴趣为应用程序创建用户首选项,请参阅PreferenceActivity,它为您提供了一个Activity框架来创建用户首选项,该框架将自动保留(使用共享首选项)。
因此,我认为这是可以的,因为仅保留了键值对。
对于原始海报,这并不难。您只需要遍历数组列表并添加项目即可。在此示例中,为简单起见,我使用了一个映射,但是您可以使用数组列表并适当地对其进行更改:
// my list of names, icon locations
Map<String, String> nameIcons = new HashMap<String, String>();
nameIcons.put("Noel", "/location/to/noel/icon.png");
nameIcons.put("Bob", "another/location/to/bob/icon.png");
nameIcons.put("another name", "last/location/icon.png");
SharedPreferences keyValues = getContext().getSharedPreferences("name_icons_list", Context.MODE_PRIVATE);
SharedPreferences.Editor keyValuesEditor = keyValues.edit();
for (String s : nameIcons.keySet()) {
// use the name as the key, and the icon as the value
keyValuesEditor.putString(s, nameIcons.get(s));
}
keyValuesEditor.commit()
您将执行类似的操作以再次读取键值对。让我知道这个是否奏效。
更新:如果您使用的是API级别11或更高版本,则有一种写出字符串集的方法
无论API级别如何,在SharedPreferences中检查String数组和Object数组
保存阵列
public boolean saveArray(String[] array, String arrayName, Context mContext) {
SharedPreferences prefs = mContext.getSharedPreferences("preferencename", 0);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(arrayName +"_size", array.length);
for(int i=0;i<array.length;i++)
editor.putString(arrayName + "_" + i, array[i]);
return editor.commit();
}
加载阵列
public String[] loadArray(String arrayName, Context mContext) {
SharedPreferences prefs = mContext.getSharedPreferences("preferencename", 0);
int size = prefs.getInt(arrayName + "_size", 0);
String array[] = new String[size];
for(int i=0;i<size;i++)
array[i] = prefs.getString(arrayName + "_" + i, null);
return array;
}
来写,
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
JSONArray jsonArray = new JSONArray();
jsonArray.put(1);
jsonArray.put(2);
Editor editor = prefs.edit();
editor.putString("key", jsonArray.toString());
System.out.println(jsonArray.toString());
editor.commit();
读书,
try {
JSONArray jsonArray2 = new JSONArray(prefs.getString("key", "[]"));
for (int i = 0; i < jsonArray2.length(); i++) {
Log.d("your JSON Array", jsonArray2.getInt(i)+"");
}
} catch (Exception e) {
e.printStackTrace();
}
共享首选项在API级别11中引入了getStringSet
和putStringSet
方法,但与旧版本的Android(仍很流行)不兼容,并且仅限于字符串集。
Android没有提供更好的方法,尤其是对于数组,遍历地图和数组以保存和加载它们并不是很容易和干净的。但是更好的实现并不难:
package com.example.utils;
import org.json.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;
import android.content.Context;
import android.content.SharedPreferences;
public class JSONSharedPreferences {
private static final String PREFIX = "json";
public static void saveJSONObject(Context c, String prefName, String key, JSONObject object) {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString(JSONSharedPreferences.PREFIX+key, object.toString());
editor.commit();
}
public static void saveJSONArray(Context c, String prefName, String key, JSONArray array) {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString(JSONSharedPreferences.PREFIX+key, array.toString());
editor.commit();
}
public static JSONObject loadJSONObject(Context c, String prefName, String key) throws JSONException {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
return new JSONObject(settings.getString(JSONSharedPreferences.PREFIX+key, "{}"));
}
public static JSONArray loadJSONArray(Context c, String prefName, String key) throws JSONException {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
return new JSONArray(settings.getString(JSONSharedPreferences.PREFIX+key, "[]"));
}
public static void remove(Context c, String prefName, String key) {
SharedPreferences settings = c.getSharedPreferences(prefName, 0);
if (settings.contains(JSONSharedPreferences.PREFIX+key)) {
SharedPreferences.Editor editor = settings.edit();
editor.remove(JSONSharedPreferences.PREFIX+key);
editor.commit();
}
}
}
现在,您可以使用这五个方法将任何集合保存在共享首选项中。使用JSONObject
和JSONArray
非常容易。您可以使用JSONArray (Collection copyFrom)
public构造函数来制作JSONArray
任何Java集合,并使用JSONArray
的get
方法来访问元素。
共享首选项没有大小限制(除了设备的存储限制),因此这些方法可以在大多数通常情况下使用,这些情况是您希望快速轻松地存储应用程序中的某些集合。但是这里会进行JSON解析,并且Android中的首选项在内部存储为XML,因此,当您处理兆字节的数据时,我建议使用其他持久性数据存储机制。
使用Gson Google库[1]的简单模式,用于复杂对象存储
public static void setComplexObject(Context ctx, ComplexObject obj){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("COMPLEX_OBJECT",new Gson().toJson(obj));
editor.commit();
}
public static ComplexObject getComplexObject (Context ctx){
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx);
String sobj = preferences.getString("COMPLEX_OBJECT", "");
if(sobj.equals(""))return null;
else return new Gson().fromJson(sobj, ComplexObject.class);
}
我使用以下代码将腰围尺寸数组(已经在我的array.xml中创建)加载到我的preferences.xml文件中。@ array / pant_inch_size是整个数组的ID。
<ListPreference
android:title="choosepantsize"
android:summary="Choose Pant Size"
android:key="pantSizePref"
android:defaultValue="34"
android:entries="@array/pant_inch_size"
android:entryValues="@array/pant_inch_size" />
这将使用数组中的选项填充菜单。我将默认大小设置为34,因此,当弹出菜单时,他们看到预先选择了大小34。
简单的方法是,将其转换为JSON String,如下例所示:
Gson gson = new Gson();
String json = gson.toJson(myObj);
然后将字符串存储在共享首选项中。一旦需要,就可以从共享首选项中获取字符串,然后转换回JSONArray或JSONObject(根据您的要求。)
写作:
private <T> void storeData(String key, T data) {
ByteArrayOutputStream serializedData = new ByteArrayOutputStream();
try {
ObjectOutputStream serializer = new ObjectOutputStream(serializedData);
serializer.writeObject(data);
} catch (IOException e) {
e.printStackTrace();
}
SharedPreferences sharedPreferences = getSharedPreferences(TAG, 0);
SharedPreferences.Editor edit = sharedPreferences.edit();
edit.putString(key, Base64.encodeToString(serializedData.toByteArray(), Base64.DEFAULT));
edit.commit();
}
阅读:
private <T> T getStoredData(String key) {
SharedPreferences sharedPreferences = getSharedPreferences(TAG, 0);
String serializedData = sharedPreferences.getString(key, null);
T storedData = null;
try {
ByteArrayInputStream input = new ByteArrayInputStream(Base64.decode(serializedData, Base64.DEFAULT));
ObjectInputStream inputStream = new ObjectInputStream(input);
storedData = (T)inputStream.readObject();
} catch (IOException|ClassNotFoundException|java.lang.IllegalArgumentException e) {
e.printStackTrace();
}
return storedData;
}
这是我成功使用的共享首选项代码,请参阅此链接:
public class MainActivity extends Activity {
private static final int RESULT_SETTINGS = 1;
Button button;
public String a="dd";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
button = (Button) findViewById(R.id.btnoptions);
setContentView(R.layout.activity_main);
// showUserSettings();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.settings, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_settings:
Intent i = new Intent(this, UserSettingActivity.class);
startActivityForResult(i, RESULT_SETTINGS);
break;
}
return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case RESULT_SETTINGS:
showUserSettings();
break;
}
}
private void showUserSettings() {
SharedPreferences sharedPrefs = PreferenceManager
.getDefaultSharedPreferences(this);
StringBuilder builder = new StringBuilder();
builder.append("\n Pet: "
+ sharedPrefs.getString("prefpetname", "NULL"));
builder.append("\n Address:"
+ sharedPrefs.getString("prefaddress","NULL" ));
builder.append("\n Your name: "
+ sharedPrefs.getString("prefname", "NULL"));
TextView settingsTextView = (TextView) findViewById(R.id.textUserSettings);
settingsTextView.setText(builder.toString());
}
}
祝您编码愉快!
您可以使用putStringSet
这样,您就可以在首选项中保存一个HashSet,如下所示:
救
Set<String> values;
SharedPreferences sharedPref =
mContext.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE);
Editor editor = sharedPref.edit();
editor.putStringSet("YOUR_KEY", values);
editor.apply();
取回
SharedPreferences sharedPref =
mContext.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE);
Editor editor = sharedPref.edit();
Set<String> newList = editor.getStringSet("YOUR_KEY", null);
putStringSet仅允许Set,这是一个无序列表。
当我对此感到困惑时,我得到了序列化解决方案,您可以在其中序列化您的字符串,但是我也想出了一个办法。
仅当您尚未阅读有关序列化的内容时,请阅读此内容,否则请继续阅读我的hack。
为了按顺序存储数组项,我们可以将数组序列化为单个字符串(通过创建一个新的类ObjectSerializer(从– www.androiddevcourse.com/objectserializer.html复制代码,替换包名称以外的所有内容))
这样放置下一个arg,这样,如果未检索到数据,它将返回空数组(我们不能将空字符串coz放入容器/变量是不是字符串的数组)
来我的hack:-
通过在每个项目之间添加一些符号,将数组的内容合并为单个字符串,然后在检索它时使用该符号对其进行拆分。使用共享首选项,可以轻松添加和检索String。如果您担心拆分,请查找“在Java中拆分字符串”。
[注意:如果您的数组内容是原始类型(例如字符串,int,float等),这将很好地工作。它将适用于具有自己结构的复杂数组,假设是电话簿,但是合并和拆分将成为有点复杂。]
PS:我是android的新手,所以不知道它是不是一个很好的hack,所以lemme知道您是否找到了更好的hack。