共有設定でクラスオブジェクトを保存および取得する


111

Androidでは、クラスのオブジェクトを共有設定に保存し、後でそのオブジェクトを取得できますか?

それができる方法は可能ですか?それが不可能な場合、それを行う他の可能性は何ですか?

シリアル化が1つのオプションであることは知っていますが、共有設定を使用して可能性を探しています。


私は誰かがそれを必要とする場合に備えてヘルパーライブラリを追加します:github.com/ionull/objectify
Tsung Goh


これは同様の質問に対する答えです。
tpk


多くの機能が組み込まれているこのライブラリを使用できます。github.com/moinkhan-in/PreferenceSpider
Moinkhan 2018

回答:


15

ありえない。

SharedPrefencesのSharePreferences.Editorに保存できるのは単純な値のみです。

特にクラスで保存する必要があるのは何ですか?


1
ありがとう。クラスの一部のデータメンバーを保存したい。共有設定を使用してデータメンバーの各値を保存したくない。オブジェクトとして保存したい。共有設定でない場合、他のオプションは何ですか。
androidGuy 2011年

5
それをシリアル化し、データベース(SQLite)/フラットファイルに保存します。
Blundell

5
答えは完全ではありません。可能な解決策は、pojoをByteArrayOutPutStreamに変換し、SharedPreferencesに文字列として保存することです
rallat

27
別のオプションはそれをjsonとして保存してから、マップに戻します。GSONまたはジャクソンと本当に簡単です
rallat

2
タイムマシンを2011年に戻してそれを理解させてください
Blundell

324

はい、Gsonを使用してこれを行うことができます

GitHubからワーキングコードをダウンロードする

SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);

保存用

Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(myObject); // myObject - instance of MyObject
prefsEditor.putString("MyObject", json);
prefsEditor.commit();

忘れる

Gson gson = new Gson();
String json = mPrefs.getString("MyObject", "");
MyObject obj = gson.fromJson(json, MyObject.class);

Update1

GSONの最新バージョンはからダウンロードすることができgithub.com/google/gson

Update2

Gradle / Android Studioを使用している場合は、build.gradle依存関係セクションに次のように入力してください-

implementation 'com.google.code.gson:gson:2.6.2'

私の場合は機能しません。libにjarを置き、ビルドパスに設定した後でも、Gsonクラスは解決されません。
Shirish Herwade 2013年

プロジェクトをクリーンにしてから@ShirishHerwadeを試してください
Parag Chauhan

@paragも機能しません。そのjarを使用して上記のエラーを削除する手順を教えてください。そのjarをlibsフォルダーに追加し、次に「java
ビルドパス

7
この回答は、その制限についても言及していればさらに良いでしょう。この方法で格納および取得できるオブジェクトの種類は?もちろん、すべてのクラスで機能するわけではありません。
wvdz 14年

3
String json = gson.toJson("MyObject");文字列ではなくオブジェクトである必要があります。
Ahmed Hegazy 2015

44

Outputstreamを使用して、オブジェクトを内部メモリに出力できます。そして、文字列に変換してから、優先的に保存します。例えば:

    mPrefs = getPreferences(MODE_PRIVATE);
    SharedPreferences.Editor ed = mPrefs.edit();
    ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();

    ObjectOutputStream objectOutput;
    try {
        objectOutput = new ObjectOutputStream(arrayOutputStream);
        objectOutput.writeObject(object);
        byte[] data = arrayOutputStream.toByteArray();
        objectOutput.close();
        arrayOutputStream.close();

        ByteArrayOutputStream out = new ByteArrayOutputStream();
        Base64OutputStream b64 = new Base64OutputStream(out, Base64.DEFAULT);
        b64.write(data);
        b64.close();
        out.close();

        ed.putString(key, new String(out.toByteArray()));

        ed.commit();
    } catch (IOException e) {
        e.printStackTrace();
    }

設定からオブジェクトを抽出する必要がある場合。以下のコードを使用してください

    byte[] bytes = mPrefs.getString(indexName, "{}").getBytes();
    if (bytes.length == 0) {
        return null;
    }
    ByteArrayInputStream byteArray = new ByteArrayInputStream(bytes);
    Base64InputStream base64InputStream = new Base64InputStream(byteArray, Base64.DEFAULT);
    ObjectInputStream in;
    in = new ObjectInputStream(base64InputStream);
    MyObject myObject = (MyObject) in.readObject();

こんにちは、これは少し前に投稿されたことを知っていますが、格納されたオブジェクトを抽出するために持っているコードが正しいことを本当に確信していますか?最後の2行で複数のエラーが発生し、単純に「新しいObjectInputStream(byteArray)」を持つのではなく、明示的なコンストラクターを定義する必要があることを示しています。助けてくれてありがとう!
Wakka Wakka Wakka 2013年

こんにちは、私は突然EOFExceptionを受け取る= new ObjectInputStream(base64InputStream); 私はあなたがしているのと全く同じ方法でそれを共有設定に書いています。何が間違っていると思いますか?
marienke 2013

Object to prefを作成するときに例外はありますか?SDKから:入力操作中にプログラムがファイルまたはストリームの終わりに遭遇したときにEOFExceptionをスローします。
Kislingk 2013

賞賛、これは私がこれまでこの問題に出会った最高の解決策です。依存関係はありません。ただし、オブジェクトにObjectOutput / InputStreamを使用できるようにするには、そのオブジェクトとその中のすべてのカスタムオブジェクトがSerializableインターフェースを実装する必要があることに注意してください。
user1112789 2015

8

私は同じ問題を抱えていました、これが私の解決策です:

共有設定に保存したいクラスMyClassとArrayList <MyClass>があります。最初に、メソッドをJSONオブジェクトに変換するメソッドをMyClassに追加しました。

public JSONObject getJSONObject() {
    JSONObject obj = new JSONObject();
    try {
        obj.put("id", this.id);
        obj.put("name", this.name);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return obj;
}

次に、オブジェクト「ArrayList <MyClass> items」を保存する方法を次に示します。

SharedPreferences mPrefs = context.getSharedPreferences("some_name", 0);
    SharedPreferences.Editor editor = mPrefs.edit();

    Set<String> set= new HashSet<String>();
    for (int i = 0; i < items.size(); i++) {
        set.add(items.get(i).getJSONObject().toString());
    }

    editor.putStringSet("some_name", set);
    editor.commit();

そして、これがオブジェクトを取得するためのメソッドです:

public static ArrayList<MyClass> loadFromStorage() {
    SharedPreferences mPrefs = context.getSharedPreferences("some_name", 0);

    ArrayList<MyClass> items = new ArrayList<MyClass>();

    Set<String> set = mPrefs.getStringSet("some_name", null);
    if (set != null) {
        for (String s : set) {
            try {
                JSONObject jsonObject = new JSONObject(s);
                Long id = jsonObject.getLong("id"));
                String name = jsonObject.getString("name");
                MyClass myclass = new MyClass(id, name);

                items.add(myclass);

            } catch (JSONException e) {
                e.printStackTrace();
         }
    }
    return items;
}

共有設定のStringSetはAPI 11以降で使用できることに注意してください。


私の問題を解決しました。何か追加したいです。最初の使用では、セットがnullかどうかを確認する必要があります。if(set!= null){for(String s:set){..}}
xevser

@xevser私は提案されたようにnullチェックを追加しました。ありがとう。
Micer

6

Gsonライブラリの使用:

dependencies {
compile 'com.google.code.gson:gson:2.8.2'
}

お店:

Gson gson = new Gson();
//Your json response object value store in json object
JSONObject jsonObject = response.getJSONObject();
//Convert json object to string
String json = gson.toJson(jsonObject);
//Store in the sharedpreference
getPrefs().setUserJson(json);

取得:

String json = getPrefs().getUserJson();

Parcelは、汎用のシリアル化メカニズムではありません。このクラス(および任意のオブジェクトをParcelに配置するための対応するParcelable API)は、高性能IPCトランスポートとして設計されています。そのため、パーセルデータを永続ストレージに配置することは適切ではありません。パーセル内のデータの基盤となる実装を変更すると、古いデータが読み取れなくなる可能性があります。
Marcos Vasconcelos

1

PowerPreferenceライブラリを使用して、3つの簡単なステップでそれを行うことができます!

https://github.com/AliAsadi/PowerPreference

1.オブジェクトを作成する

Object obj = new Object();

2.共有設定に書き込む

PowerPreference.getDefaultFile().put("object",obj);

3.オブジェクトを取得する

Object obj = PowerPreference.getDefaultFile()
                            .getObject("object", Object.class);

0

このオブジェクトの使用-> TinyDB--Android-Shared-Preferences-Turboは非常にシンプルです。配列、整数、文字列リストなどの一般的に使用されるオブジェクトのほとんどを保存できます


かっこいいですが、これはカスタムオブジェクト(POJOS)ではなく、プリミティブタイプ(String、double、intなど)にのみ機能すると思います
CommonSenseCode

カスタムオブジェクトで機能するようになりました
。ReadMeを

0

あなたは使用することができますフェリペシルベストルので- Androidの複雑な設定をカスタムオブジェクトを格納するためのライブラリ。基本的に、GSONメカニズムを使用してオブジェクトを格納します。

オブジェクトを設定に保存するには:

User user = new User();
user.setName("Felipe");
user.setAge(22); 
user.setActive(true); 

ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences(
     this, "mypref", MODE_PRIVATE);
complexPreferences.putObject("user", user);
complexPreferences.commit();

そしてそれを取り戻すには:

ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences(this, "mypref", MODE_PRIVATE);
User user = complexPreferences.getObject("user", User.class);

Parcelは、汎用のシリアル化メカニズムではありません。このクラス(および任意のオブジェクトをParcelに配置するための対応するParcelable API)は、高性能IPCトランスポートとして設計されています。そのため、パーセルデータを永続ストレージに配置することは適切ではありません。パーセル内のデータの基盤となる実装を変更すると、古いデータが読み取れなくなる可能性があります。
Marcos Vasconcelos

これは非推奨です
IgorGanapolsky

0

Gradle Build.gradleを使用してGSONを使用できます。

implementation 'com.google.code.gson:gson:2.8.0'

次に、コード内で、たとえばKotlinを使用したstring / booleanのペア:

        val nestedData = HashMap<String,Boolean>()
        for (i in 0..29) {
            nestedData.put(i.toString(), true)
        }
        val gson = Gson()
        val jsonFromMap = gson.toJson(nestedData)

SharedPrefsへの追加:

        val sharedPrefEditor = context.getSharedPreferences(_prefName, Context.MODE_PRIVATE).edit()
        sharedPrefEditor.putString("sig_types", jsonFromMap)
        sharedPrefEditor.apply()

次に、データを取得します。

val gson = Gson()
val sharedPref: SharedPreferences = context.getSharedPreferences(_prefName, Context.MODE_PRIVATE)
val json = sharedPref.getString("sig_types", "false")
val type = object : TypeToken<Map<String, Boolean>>() {}.type
val map = gson.fromJson(json, type) as LinkedTreeMap<String,Boolean>
for (key in map.keys) {
     Log.i("myvalues", key.toString() + map.get(key).toString())
}

Parcelは、汎用のシリアル化メカニズムではありません。このクラス(および任意のオブジェクトをParcelに配置するための対応するParcelable API)は、高性能IPCトランスポートとして設計されています。そのため、パーセルデータを永続ストレージに配置することは適切ではありません。パーセル内のデータの基盤となる実装を変更すると、古いデータが読み取れなくなる可能性があります。
Marcos Vasconcelos

0

Common Shared Preferences(CURD)SharedPreference:単純なKotlinクラスを使用して、値とキーのペアの形式でデータを保存します。

var sp = SharedPreference(this);

データの保存:

String、Int、およびBooleanデータを格納するために、同じ名前と異なるパラメーターを持つ3つのメソッドがあります(メソッドのオーバーロード)。

save("key-name1","string value")
save("key-name2",int value)
save("key-name3",boolean)

データの取得:SharedPreferencesに保存されているデータを取得するには、次のメソッドを使用します。

sp.getValueString("user_name")
sp.getValueInt("user_id")
sp.getValueBoolean("user_session",true)

すべてのデータをクリア:SharedPreferences全体をクリアするには、以下のコードを使用します。

 sp.clearSharedPreference()

特定のデータを削除:

sp.removeValue("user_name")

共通の共有設定クラス

import android.content.Context
import android.content.SharedPreferences

class SharedPreference(private val context: Context) {
    private val PREFS_NAME = "coredata"
    private val sharedPref: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
    //********************************************************************************************** save all
    //To Store String data
    fun save(KEY_NAME: String, text: String) {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.putString(KEY_NAME, text)
        editor.apply()
    }
    //..............................................................................................
    //To Store Int data
    fun save(KEY_NAME: String, value: Int) {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.putInt(KEY_NAME, value)
        editor.apply()
    }
    //..............................................................................................
    //To Store Boolean data
    fun save(KEY_NAME: String, status: Boolean) {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.putBoolean(KEY_NAME, status)
        editor.apply()
    }
    //********************************************************************************************** retrieve selected
    //To Retrieve String
    fun getValueString(KEY_NAME: String): String? {

        return sharedPref.getString(KEY_NAME, "")
    }
    //..............................................................................................
    //To Retrieve Int
    fun getValueInt(KEY_NAME: String): Int {

        return sharedPref.getInt(KEY_NAME, 0)
    }
    //..............................................................................................
    // To Retrieve Boolean
    fun getValueBoolean(KEY_NAME: String, defaultValue: Boolean): Boolean {

        return sharedPref.getBoolean(KEY_NAME, defaultValue)
    }
    //********************************************************************************************** delete all
    // To clear all data
    fun clearSharedPreference() {

        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.clear()
        editor.apply()
    }
    //********************************************************************************************** delete selected
    // To remove a specific data
    fun removeValue(KEY_NAME: String) {
        val editor: SharedPreferences.Editor = sharedPref.edit()
        editor.remove(KEY_NAME)
        editor.apply()
    }
}

ブログ:https : //androidkeynotes.blogspot.com/2020/02/shared-preference.html


-2

SharedPreferencesにオブジェクトを保存する方法はありません。私が行ったのは、パブリッククラスを作成し、必要なすべてのパラメーターを設定して、セッターとゲッターを作成し、オブジェクトにアクセスできました。


-3

アプリケーションがドンをシャットダウンした後、または実行中にオブジェクトを取得する必要がありますか?

データベースに保存できます。
または、単にカスタムアプリケーションクラスを作成します。

public class MyApplication extends Application {

    private static Object mMyObject;
    // static getter & setter
    ...
}

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application ... android:name=".MyApplication">
        <activity ... />
        ...
    </application>
    ...
</manifest>

そして、すべての活動から:

((MyApplication) getApplication).getMyObject();

本当に最善の方法ではありませんが、うまくいきます。


-6

はい。Sharedpreferenceを使用してオブジェクトを保存および取得できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.