名前とアイコン ポインターを持つArrayList
の オブジェクトがあり、 に保存したいと考えていますSharedPreferences
。どのようにできるのか?
注: データベースは使いたくない
名前とアイコン ポインターを持つArrayList
の オブジェクトがあり、 に保存したいと考えていますSharedPreferences
。どのようにできるのか?
注: データベースは使いたくない
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();
}
同じことを行う他の方法:
//Retrieve the values
Gson gson = new Gson();
String jsonText = Prefs.getString("key", null);
String[] text = gson.fromJson(jsonText, String[].class); //EDIT: gso to gson
//Set the values
Gson gson = new Gson();
List<String> textList = new ArrayList<String>(data);
String jsonText = gson.toJson(textList);
prefsEditor.putString("key", jsonText);
prefsEditor.apply();
Java での GSON の使用:
public void saveArrayList(ArrayList<String> list, String key){
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
SharedPreferences.Editor editor = prefs.edit();
Gson gson = new Gson();
String json = gson.toJson(list);
editor.putString(key, json);
editor.apply();
}
public ArrayList<String> getArrayList(String key){
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
Gson gson = new Gson();
String json = prefs.getString(key, null);
Type type = new TypeToken<ArrayList<String>>() {}.getType();
return gson.fromJson(json, type);
}
Kotlin での GSON の使用
fun saveArrayList(list: java.util.ArrayList<String?>?, key: String?) {
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity)
val editor: Editor = prefs.edit()
val gson = Gson()
val json: String = gson.toJson(list)
editor.putString(key, json)
editor.apply()
}
fun getArrayList(key: String?): java.util.ArrayList<String?>? {
val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(activity)
val gson = Gson()
val json: String = prefs.getString(key, null)
val type: Type = object : TypeToken<java.util.ArrayList<String?>?>() {}.getType()
return gson.fromJson(json, type)
}
したがって、 Data Storageの Android 開発者サイトから:
ユーザー設定
共有設定は、ユーザーが選択した着信音などの「ユーザー設定」を厳密に保存するためのものではありません。アプリケーションのユーザー設定の作成に関心がある場合は、PreferenceActivity を参照してください。これは、(共有設定を使用して) 自動的に永続化されるユーザー設定を作成するためのアクティビティ フレームワークを提供します。
永続化されるのはキーと値のペアだけなので、問題ないと思います。
元のポスターにとって、これはそれほど難しいことではありません。配列リストを反復処理して項目を追加するだけです。この例では、わかりやすくするためにマップを使用していますが、配列リストを使用して適切に変更することもできます。
// 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 レベル 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();
}
}
}
この 5 つの方法を使用して、任意のコレクションを共有設定に保存できるようになりました。と の操作JSONObject
はJSONArray
非常に簡単です。JSONArray (Collection copyFrom)
public コンストラクターを使用JSONArray
して任意の Java コレクションからを作成し、JSONArray
のget
メソッドを使用して要素にアクセスできます。
共有設定には (デバイスのストレージ制限以外に) サイズ制限がないため、これらの方法は、アプリ内のコレクションをすばやく簡単に保存したい通常のほとんどの場合に機能します。ただし、JSON の解析はここで行われ、Android の設定は内部で XML として保存されるため、メガバイトのデータを扱う場合は、他の永続的なデータ ストア メカニズムを使用することをお勧めします。
以下のコードを使用して、ウエスト サイズの配列 (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 文字列に変換することです。
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;
}
これに悩まされたとき、文字列をシリアル化できるシリアル化ソリューションを手に入れましたが、ハックも思いつきました。
シリアル化について読んでいない場合にのみ、これを読んでください。それ以外の場合は、下に行って私のハックを読んでください
配列項目を順番に格納するために、配列を単一の文字列にシリアル化できます (新しいクラス ObjectSerializer を作成します (コードを www.androiddevcourse.com/objectserializer.html からコピーし、パッケージ名以外をすべて置き換えます))。
データが取得されない場合に空の配列が返されるように、次の引数を次のように配置します (コンテナー/変数が文字列ではなく配列であるため、空の文字列を配置することはできません)。
私のハックに来ます:-
配列の内容を単一の文字列にマージするには、各項目の間に記号を挿入し、取得時にその記号を使用して分割します。文字列の追加と取得は、設定を共有することで簡単です。分割が心配な場合は、「Java で文字列を分割する」を参照してください。
[注: 配列の内容が string、int、float などのプリミティブな種類の場合、これは正常に機能します。電話帳を想定すると、独自の構造を持つ複雑な配列でも機能しますが、マージと分割はちょっと複雑。]
PS:私はアンドロイドが初めてなので、それが良いハックかどうかわからないので、より良いハックを見つけたら教えてください.