Mam ArrayList
obiekt, który ma nazwę i wskaźnik ikony i chcę go zapisać SharedPreferences
. Jak mam to zrobić?
UWAGA: nie chcę korzystać z bazy danych
Odpowiedzi:
A więc z witryny programistów Androida na temat przechowywania danych :
Preferencje użytkownika
Preferencje wspólne nie służą wyłącznie do zapisywania „preferencji użytkownika”, takich jak wybrany dzwonek. Jeśli jesteś zainteresowany tworzeniem preferencji użytkownika dla swojej aplikacji, zobacz PreferenceActivity, który zapewnia strukturę działania umożliwiającą tworzenie preferencji użytkownika, które zostaną automatycznie utrwalone (przy użyciu preferencji współdzielonych).
Myślę więc, że jest to w porządku, ponieważ są to po prostu pary klucz-wartość, które są utrwalane.
Dla oryginalnego plakatu nie jest to takie trudne. Po prostu przeglądasz listę tablic i dodajesz elementy. W tym przykładzie używam mapy dla uproszczenia, ale możesz użyć listy tablic i odpowiednio ją zmienić:
// 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()
Zrobiłbyś coś podobnego, aby ponownie odczytać pary klucz-wartość. Daj mi znać, czy to działa.
Aktualizacja: jeśli używasz poziomu interfejsu API 11 lub nowszego, istnieje metoda zapisywania zestawu ciągów
Niezależnie od poziomu interfejsu API, sprawdź tablice ciągów i tablice obiektów w SharedPreferences
ZAPISZ ARRAY
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();
}
LOAD ARRAY
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;
}
Pisać,
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();
Czytać,
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();
}
Wspólne preferencje wprowadziły metody a getStringSet
i putStringSet
w API Level 11, ale nie jest to zgodne ze starszymi wersjami systemu Android (które są nadal popularne), a także ogranicza się do zestawów ciągów.
Android nie zapewnia lepszych metod, a zapętlanie map i tablic w celu ich zapisywania i ładowania nie jest łatwe i czyste, szczególnie w przypadku tablic. Ale lepsza implementacja nie jest taka trudna:
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();
}
}
}
Teraz możesz zapisać dowolną kolekcję we wspólnych preferencjach za pomocą tych pięciu metod. Praca z JSONObject
i JSONArray
jest bardzo łatwa. Można użyć JSONArray (Collection copyFrom)
konstruktora publicznego zrobić JSONArray
z jakiegokolwiek gromadzenia i wykorzystywania Java JSONArray
„s get
metody dostępu do elementów.
Nie ma limitu rozmiaru dla wspólnych preferencji (poza limitami pamięci urządzenia), więc te metody mogą działać w większości typowych przypadków, w których potrzebujesz szybkiego i łatwego przechowywania niektórych kolekcji w swojej aplikacji. Ale tutaj odbywa się parsowanie JSON, a preferencje w Androidzie są wewnętrznie przechowywane jako XML, więc zalecam używanie innych trwałych mechanizmów przechowywania danych, gdy masz do czynienia z megabajtami danych.
Łatwy tryb do przechowywania złożonych obiektów z wykorzystaniem biblioteki 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);
}
Załadowałem tablicę rozmiarów talii (już utworzoną w moim array.xml) do mojego pliku preferencji.xml za pomocą poniższego kodu. @ array / pant_inch_size to identyfikator całej tablicy.
<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" />
To zapełniło menu opcjami z tablicy. Ustawiam domyślny rozmiar na 34, więc kiedy wyskakuje menu, widzą, że rozmiar 34 jest wstępnie wybrany.
Prostym sposobem jest przekonwertowanie go na ciąg JSON, jak na poniższym przykładzie:
Gson gson = new Gson();
String json = gson.toJson(myObj);
Następnie zapisz ciąg we wspólnych preferencjach. Gdy będziesz go potrzebować, po prostu pobierz ciąg ze wspólnych preferencji i przekonwertuj z powrotem na JSONArray lub JSONObject (zgodnie z wymaganiami).
Do pisania:
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();
}
Do czytania:
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;
}
To jest kod wspólnych preferencji, którego używam z powodzeniem, Skorzystaj z tego linku :
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());
}
}
SZCZĘŚLIWEGO KODOWANIA!
Możesz użyć putStringSet
Dzięki temu możesz zapisać zestaw HashSet w swoich preferencjach, tak jak to:
Zapisać
Set<String> values;
SharedPreferences sharedPref =
mContext.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE);
Editor editor = sharedPref.edit();
editor.putStringSet("YOUR_KEY", values);
editor.apply();
Odzyskaj
SharedPreferences sharedPref =
mContext.getSharedPreferences(PREF_KEY, Context.MODE_PRIVATE);
Editor editor = sharedPref.edit();
Set<String> newList = editor.getStringSet("YOUR_KEY", null);
PutStringSet dopuszcza tylko zestaw i jest to lista nieuporządkowana .
Kiedy mnie to podsunęło, dostałem rozwiązanie do serializacji, w którym możesz serializować swój ciąg, ale ja też wymyśliłem hack.
Przeczytaj to tylko, jeśli nie czytałeś o serializacji, w przeciwnym razie zejdź na dół i przeczytaj mój hack
Aby uporządkować elementy tablicy, możemy serializować tablicę w jeden ciąg (tworząc nową klasę ObjectSerializer (skopiuj kod z - www.androiddevcourse.com/objectserializer.html, zamień wszystko oprócz nazwy pakietu))
Wprowadzanie danych w preferencjach wspólnych:
Umieść następny argument jako taki, aby jeśli dane nie zostały pobrane, zwróciły pustą tablicę (nie możemy wstawić pustego ciągu, ponieważ kontener / zmienna jest tablicą, a nie ciągiem)
Jadąc do mojego hacka: -
Połącz zawartość tablicy w jeden ciąg, umieszczając jakiś symbol między każdym elementem, a następnie podziel go za pomocą tego symbolu podczas pobierania. Dzięki wspólnym preferencjom dodawanie i pobieranie String jest łatwe. Jeśli martwisz się o podział, po prostu wyszukaj „dzielenie łańcucha w java”.
[Uwaga: Działa to dobrze, jeśli zawartość twojej tablicy jest prymitywnego rodzaju, jak string, int, float, itp. Będzie działać dla złożonych tablic, które mają własną strukturę, przypuśćmy, że książka telefoniczna, ale scalanie i dzielenie stanie się nieco skomplikowane. ]
PS: Jestem nowy w Androidzie, więc nie wiem, czy to dobry hack, więc daj mi znać, jeśli znajdziesz lepsze hacki.