У мене є ArrayList
об'єкти, що мають ім'я та вказівник на піктограму, і я хочу зберегти їх у SharedPreferences
. Як я можу зробити?
ПРИМІТКА: Я не хочу використовувати базу даних
Відповіді:
Отже, з веб-сайту розробника Android щодо зберігання даних :
Налаштування користувача
Спільні налаштування не є суто для збереження "користувацьких уподобань", таких як те, який сигнал дзвінка вибрав користувач. Якщо ви зацікавлені у створенні користувацьких уподобань для вашого додатка, див.
Тому я думаю, що це нормально, оскільки це просто просто пари ключ-значення, які зберігаються.
Для оригінального плаката це не так складно. Ви просто переглядаєте список масивів і додаєте елементи. У цьому прикладі я використовую карту для простоти, але ви можете використовувати список масивів і правильно його змінити:
// 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
ЗБЕРЕГТИ МАСИВУ
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();
}
Спільні уподобання представили a getStringSet
та putStringSet
методи на рівні API 11, але це не сумісно зі старими версіями 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)
публічний конструктор, щоб створити JSONArray
будь-яку колекцію Java та використовувати методи JSONArray
'' get
для доступу до елементів.
Немає обмежень розміру для спільних налаштувань (крім обмежень пам’яті пристрою), тому ці методи можуть працювати в більшості звичайних випадків, коли ви хочете швидко і просто зберігати деяку колекцію у своєму додатку. Але аналіз JSON відбувається тут, і налаштування в Android зберігаються як XML всередині, тому я рекомендую використовувати інші постійні механізми зберігання даних, коли ви маєте справу з мегабайтами даних.
Простий режим для зберігання складних об’єктів за допомогою бібліотеки Google Gson [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 - це ідентифікатор усього масиву.
<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, і це невпорядкований список.
Коли мене з цим прослуховували, я отримав рішення для серіалізації, де ви можете серіалізувати свій рядок, але я також придумав хак.
Читайте це, лише якщо ви ще не читали про серіалізацію, інакше спуститесь і прочитайте мій хак
Для того, щоб зберігати елементи масиву в порядку, ми можемо серіалізувати масив в один рядок (створивши новий клас ObjectSerializer (скопіюйте код з - www.androiddevcourse.com/objectserializer.html, замініть все, крім імені пакета))
Введення даних у Спільні налаштування:
Поставте наступний аргумент як такий, щоб, якщо дані не отримано, він повернув порожній масив (ми не можемо помістити порожній рядок, оскільки контейнер / змінна є масивом, а не рядком)
До мого зламу: -
Об’єднайте вміст масиву в один рядок, маючи якийсь символ між кожним елементом, а потім розділіть його, використовуючи цей символ під час отримання. Coz додавання та отримання рядка легко за допомогою спільних налаштувань. Якщо ви стурбовані розділенням, просто шукайте "розділення рядка в Java".
[Примітка: Це чудово працює, якщо вміст вашого масиву примітивного типу, як рядок, int, float тощо. Це буде працювати для складних масивів, які мають власну структуру, припустимо телефонну книгу, але злиття та розбиття стане трохи складний. ]
PS: Я новачок в android, тому не знаю, чи це хороший хак, тому lemme знає, чи знайдете ви кращі хаки.