menyimpan dan mengambil objek kelas dalam preferensi bersama

111

Di Android, bisakah kita menyimpan objek kelas dalam preferensi bersama dan mengambil objek itu nanti?

Jika memungkinkan, bagaimana melakukannya? Jika tidak memungkinkan apa kemungkinan lain untuk melakukannya?

Saya tahu bahwa serialisasi adalah salah satu opsi, tetapi saya mencari kemungkinan menggunakan preferensi bersama.

androidGuy
sumber
Saya menambahkan perpustakaan pembantu jika seseorang membutuhkannya: github.com/ionull/objectify
Tsung Goh
Ini adalah contoh thegeekyland.blogspot.com/2015/11/…
Arlind
Inilah jawaban untuk pertanyaan serupa.
tpk
Anda dapat menggunakan perpustakaan ini yang memiliki banyak fitur bawaan. github.com/moinkhan-in/PreferenceSpider
Moinkhan

Jawaban:

15

Tidak memungkinkan.

Anda hanya dapat menyimpan, nilai sederhana di SharedPrefences SharePreferences.Editor

Terutama tentang kelas apa yang perlu Anda selamatkan?

Blundell
sumber
1
Terima kasih, saya ingin menyimpan beberapa data anggota kelas, dan saya tidak ingin menyimpan setiap nilai anggota data menggunakan preferensi bersama, saya ingin menyimpannya sebagai objek. Jika tidak preferensi bersama, apa pilihan saya yang lain?
androidGuy
5
Serialisasi dan simpan, dalam database (SQLite) / dalam file datar.
Blundell
5
Jawabannya belum lengkap. Solusi yang mungkin adalah mengubah pojo menjadi ByteArrayOutPutStream dan menyimpan sebagai String di SharedPreferences
lakukan
27
pilihan lain adalah menyimpannya sebagai json dan kemudian memetakannya kembali. Dengan GSON atau jackSON sangat mudah
lakukan reli
2
biarkan saya mengembalikan mesin waktu saya ke tahun 2011 dan mencari tahu
Blundell
324

Ya, kami dapat melakukan ini menggunakan Gson

Unduh kode Kerja dari GitHub

SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);

Untuk disimpan

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

Untuk mendapatkan

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

Pembaruan1

Versi terbaru GSON dapat diunduh dari github.com/google/gson .

Pembaruan2

Jika Anda menggunakan Gradle / Android Studio, cukup masukkan berikut ini di build.gradlebagian dependensi -

implementation 'com.google.code.gson:gson:2.6.2'
Parag Chauhan
sumber
tidak bekerja dalam kasus saya. Bahkan setelah meletakkan jar di libs dan menyetel di jalur build, kelas Gson tidak terselesaikan.
Shirish Herwade
Bersihkan proyek lalu coba @ShirishHerwade
Parag Chauhan
@parag itu juga tidak berfungsi. Bisakah Anda memberi tahu saya langkah-langkah untuk menggunakan toples itu untuk menghapus kesalahan di atas. Karena saya berhasil menambahkan jar itu di folder libs dan kemudian di "java build path" juga mencoba menambahkan json penyimpanan eksternal di desktop saya
Shirish Herwade
7
Jawaban ini akan lebih baik jika disebutkan juga batasannya. Jenis objek apa yang dapat dan tidak dapat kita simpan dan ambil dengan cara ini? Jelas ini tidak akan bekerja untuk semua kelas.
wvdz
3
String json = gson.toJson("MyObject");harus menjadi objek bukan String.
Ahmed Hegazy
44

kita dapat menggunakan Outputstream untuk mengeluarkan Object kita ke memori internal. Dan konversikan ke string lalu simpan dalam preferensi. Sebagai contoh:

    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();
    }

saat kita perlu mengekstrak Objek dari Preferensi. Gunakan kode seperti di bawah ini

    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();
Kislingk
sumber
Hai, Saya tahu ini telah diposting beberapa waktu yang lalu, tetapi apakah Anda yakin kode yang Anda miliki untuk mengekstrak objek yang disimpan sudah benar? Saya mendapatkan beberapa kesalahan pada 2 baris terakhir yang mengeluh tentang bagaimana konstruktor eksplisit perlu didefinisikan daripada hanya memiliki "ObjectInputStream baru (byteArray)". Terima kasih untuk bantuannya!
Wakka Wakka Wakka
Hai, saya tiba-tiba mendapatkan EOFException di in = new ObjectInputStream (base64InputStream); Saya menulisnya ke preferensi bersama dengan cara yang persis sama dengan yang Anda lakukan. Menurut Anda apa yang mungkin salah?
marienke
Apakah Anda memiliki pengecualian saat menulis Object to pref? Dari SDK: Dilemparkan EOFException saat program menemui akhir file atau aliran selama operasi input.
Kislingk
Kudos, ini adalah solusi terbaik yang saya temukan untuk masalah ini sejauh ini. Tidak ada ketergantungan. Namun, perlu dicatat bahwa untuk dapat menggunakan ObjectOutput / InputStream untuk sebuah objek, objek tersebut dan semua objek kustom di dalamnya harus mengimplementasikan antarmuka Serializable.
pengguna1112789
8

Saya memiliki masalah yang sama, inilah solusi saya:

Saya memiliki kelas MyClass dan ArrayList <MyClass> yang ingin saya simpan ke Preferensi Bersama. Pada awalnya saya telah menambahkan metode ke MyClass yang mengubahnya menjadi objek JSON:

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;
}

Lalu inilah metode untuk menyimpan objek "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();

Dan inilah metode untuk mengambil objek:

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;
}

Perhatikan bahwa StringSet di Preferensi Bersama tersedia sejak API 11.

Micer
sumber
Memecahkan masalah saya. Saya ingin menambahkan sesuatu. Untuk penggunaan pertama kita harus memeriksa apakah setnya null. if (set! = null) {untuk (String s: set) {..}}
xevser
@xevser Saya telah menambahkan pemeriksaan null seperti yang disarankan. Terima kasih.
Micer
6

Menggunakan Gson Library:

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

Toko:

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);

Ambil:

String json = getPrefs().getUserJson();
Ramesh sambu
sumber
Parcel bukanlah mekanisme serialisasi tujuan umum. Kelas ini (dan Parcelable API terkait untuk menempatkan objek arbitrer ke dalam Parcel) dirancang sebagai transport IPC berperforma tinggi. Karena itu, tidak tepat untuk menempatkan data Parcel apa pun ke dalam penyimpanan persisten: perubahan dalam implementasi yang mendasari data apa pun di Parcel dapat membuat data yang lebih lama tidak dapat dibaca.
Marcos Vasconcelos
1

Anda dapat melakukannya menggunakan PowerPreferenceperpustakaan dalam 3 langkah mudah!

https://github.com/AliAsadi/PowerPreference

1. Buat Objek

Object obj = new Object();

2. Tulis ke preferensi bersama

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

3. Mendapatkan objeknya

Object obj = PowerPreference.getDefaultFile()
                            .getObject("object", Object.class);
Ali Asadi
sumber
0

Menggunakan objek ini -> TinyDB - Android-Shared-Preferences-Turbo sangat sederhana. Anda dapat menyimpan sebagian besar objek yang umum digunakan dengannya seperti array, integer, daftar string, dll

kc ochibili.dll
sumber
Keren, tapi saya pikir ini hanya berfungsi untuk jenis primitie (String, double, int, dll) bukan untuk objek khusus (POJOS)
CommonSenseCode
sekarang berfungsi untuk objek khusus, periksa ReadMe, itu telah diperbarui
kc ochibili
0

Anda dapat menggunakan Preferensi Kompleks Android - oleh perpustakaan Felipe Silvestre untuk menyimpan objek khusus Anda. Pada dasarnya, ini menggunakan mekanisme GSON untuk menyimpan objek.

Untuk menyimpan objek ke prefs:

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();

Dan untuk mengambilnya kembali:

ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences(this, "mypref", MODE_PRIVATE);
User user = complexPreferences.getObject("user", User.class);
Serhii Hrabas
sumber
Parcel bukanlah mekanisme serialisasi tujuan umum. Kelas ini (dan Parcelable API terkait untuk menempatkan objek arbitrer ke dalam Parcel) dirancang sebagai transport IPC berperforma tinggi. Oleh karena itu, tidak tepat untuk menempatkan data Parcel apa pun ke dalam penyimpanan persisten: perubahan dalam implementasi yang mendasari data apa pun di Parcel dapat membuat data lama tidak dapat dibaca.
Marcos Vasconcelos
Ini sudah usang
IgorGanapolsky
0

Anda dapat menggunakan GSON, menggunakan Gradle Build.gradle:

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

Kemudian di kode Anda, misalnya pasangan string / boolean dengan Kotlin:

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

Menambahkan ke SharedPrefs:

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

Sekarang untuk mengambil data:

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())
}
CAZ
sumber
Parcel bukanlah mekanisme serialisasi tujuan umum. Kelas ini (dan Parcelable API terkait untuk menempatkan objek arbitrer ke dalam Parcel) dirancang sebagai transport IPC berperforma tinggi. Karena itu, tidak tepat untuk menempatkan data Parcel apa pun ke dalam penyimpanan persisten: perubahan dalam implementasi yang mendasari data apa pun di Parcel dapat membuat data yang lebih lama tidak dapat dibaca.
Marcos Vasconcelos
0

Preferensi bersama umum (CURD) SharedPreference: untuk Menyimpan data dalam bentuk pasangan nilai-kunci dengan kelas Kotlin sederhana.

var sp = SharedPreference(this);

Menyimpan Data:

Untuk menyimpan data String, Int dan Boolean kami memiliki tiga metode dengan nama yang sama dan parameter berbeda (Metode overloading).

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

Ambil Data: Untuk Mengambil data yang disimpan di SharedPreferences gunakan metode berikut.

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

Hapus Semua Data: Untuk menghapus seluruh SharedPreferences gunakan kode di bawah ini.

 sp.clearSharedPreference()

Hapus Data Tertentu:

sp.removeValue("user_name")

Kelas Preferensi Bersama Umum

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()
    }
}

Blog: https://androidkeynotes.blogspot.com/2020/02/shared-preference.html

Hari Shankar S.
sumber
-2

Tidak ada cara untuk menyimpan objek di SharedPreferences, Yang saya lakukan adalah membuat kelas publik, meletakkan semua parameter yang saya butuhkan dan membuat penyetel dan pengambil, saya dapat mengakses objek saya,

Ismael ozil
sumber
-3

Apakah Anda perlu mengambil objek bahkan setelah aplikasi ditutup atau hanya selama sedang berjalan?

Anda bisa menyimpannya ke dalam database.
Atau Cukup buat kelas Aplikasi kustom.

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>

Kemudian dari setiap aktivitas dilakukan:

((MyApplication) getApplication).getMyObject();

Bukan cara terbaik tetapi berhasil.

luc.chante
sumber
-6

Ya, Anda dapat menyimpan dan mengambil objek menggunakan Sharedpreference

Sukanya
sumber