зберігати та отримувати об’єкт класу у спільних налаштуваннях


111

Чи можна в Android зберігати об’єкт класу у спільних уподобаннях та отримувати об’єкт пізніше?

Якщо можливо, як це зробити? Якщо це неможливо, які інші можливості зробити це?

Я знаю, що серіалізація - це один варіант, але я шукаю можливості, використовуючи спільні переваги.


Я додаю бібліотеку помічників, якщо комусь це потрібно: github.com/ionull/objectify
Goh


Ось відповідь на подібне запитання.
tpk


Ви можете користуватися цією бібліотекою, в якій багато вбудованих феод. github.com/moinkhan-in/PreferenceSpider
Moinkhan

Відповіді:


15

Неможливо.

Ви можете зберігати прості значення лише в SharedPrefences SharePreferences.Editor

Що конкретно щодо класу вам потрібно зберегти?


1
Дякую.Я хочу зберігати деякі члени даних класу. І я не хочу зберігати кожне значення членів даних, використовуючи спільні налаштування. Я хочу зберігати їх як об'єкт. Якщо немає спільних переваг, які інші мої параметри?
androidGuy

5
Серіалізуйте його та зберігайте у базі даних (SQLite) / у плоскому файлі.
Блонделл

5
Відповідь не повна. Можливе рішення - перетворити pojo в ByteArrayOutPutStream і зберегти як String у SharedPreferences
rallat

27
інший варіант зберігається як json, а потім відображається назад. З GSON або jackSON це дуже просто
зібратися

2
дозвольте мені повернути свою машину часу до 2011 року та зрозуміти це
Блонделл

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

Оновлення1

Останню версію GSON можна завантажити з github.com/google/gson .

Оновлення2

Якщо ви використовуєте Gradle / Android Studio, просто введіть наступні build.gradleрозділи в залежності -

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

не працює в моєму випадку. Навіть після того, як поставити банку в libs та встановити шлях складання, клас Gson не вирішується.
Shirish Herwade

Очистіть проект, тоді спробуйте @ShirishHerwade
Parag Chauhan

@parag, що також не працює. Скажіть, будь ласка, кроки, щоб скористатися цією баночкою для видалення вищевказаної помилки. Оскільки я успішно додав цю банку в папку libs, а потім у "java build path", також спробував додати зовнішнє зберігання json на робочому столі
Shirish Herwade

7
Ця відповідь була б ще кращою, якби вона також згадувала свої обмеження. Який об’єкт можна і чи не можемо ми зберігати та отримувати таким чином? Очевидно, це працюватиме не для всіх класів.
wvdz

3
String json = gson.toJson("MyObject");повинен бути об'єктом, а не рядком.
Ахмед Гегазі

44

ми можемо використовувати вихідний потік для виведення нашого Об'єкту у внутрішню пам'ять. І перетворити в рядок, а потім зберегти у перевазі. Наприклад:

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

Привіт, я знаю, що це було розміщено деякий час тому, але ви впевнені, що код, який ви маєте для вилучення збереженого об'єкта, правильний? У останніх двох рядках я отримую декілька помилок, примхливі про те, як потрібно визначати явні конструктори, а не просто мати "новий ObjectInputStream (byteArray)". Дякую за допомогу!
Wakka Wakka Wakka

Привіт, я раптом отримую EOFException у в = новому ObjectInputStream (base64InputStream); Я пишу це спільним префіксам точно так само, як ви робите. Як ви думаєте, що може бути не так?
marienke

Чи є у вас якісь винятки, коли ви пишете Object to pref? З SDK: Thrown EOFException, коли програма стикається з кінцем файлу або потоку під час операції введення.
Кіслінгк

Кудо, це найкраще рішення до цього часу, з яким я зіткнувся. Ніяких залежностей. Однак слід зазначити, що для того, щоб мати можливість використовувати ObjectOutput / InputStream для об'єкта, зазначений об'єкт та всі власні об'єкти всередині нього повинні реалізувати інтерфейс Serializable.
користувач1112789

8

У мене була така ж проблема, ось моє рішення:

У мене є клас MyClass і ArrayList <MyClass>, які я хочу зберегти до спільних налаштувань. Спочатку я додав метод до MyClass, який перетворює його в об'єкт 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;
}

Тоді ось метод збереження об’єкта "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.


Вирішив мою проблему. Я хочу щось додати. Для першого використання ми повинні перевірити, чи не встановлено нульове значення. if (set! = null) {for (Рядок s: set) {..}}
xevser

@xevser Я додав нульову перевірку, як було запропоновано. Дякую.
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();

Посилка не є механізмом серіалізації загального призначення. Цей клас (і відповідний API Parcelable для розміщення довільних об'єктів у посилці) розроблений як високоефективний транспорт IPC. Таким чином, недоцільно розміщувати будь-які дані посилок для постійного зберігання: зміни в базовій реалізації будь-якого з даних у посилці можуть зробити старі дані нечитабельними.
Маркос Васконцелос

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 його дуже просто. ви можете зберегти більшість часто використовуваних об'єктів, як-от масиви, цілі числа, списки рядків тощо


Класно, але я думаю, що це працює лише для типів примітивів (String, double, int тощо), а не для користувацьких об'єктів (POJOS)
CommonSenseCode

тепер він працює для користувацьких об’єктів, перевіряйте ReadMe, оновлено
kc ochibili

0

Ви можете використовувати комплексні налаштування Android - від Felipe Silvestre бібліотеки для зберігання власних об'єктів. В основному, він використовує механізм 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);

Посилка не є механізмом серіалізації загального призначення. Цей клас (і відповідний API Parcelable для розміщення довільних об'єктів у посилці) розроблений як високоефективний транспорт IPC. Таким чином, недоцільно розміщувати будь-які дані посилок для постійного зберігання: зміни в базовій реалізації будь-якого з даних у посилці можуть зробити старі дані нечитабельними.
Маркос Васконцелос

Це застаріло
ІгорГанапольський

0

Ви можете використовувати GSON, використовуючи Gradle Build.gradle:

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

Тоді у своєму коді, наприклад, пара рядків / булевих з Kotlin:

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

Посилка не є механізмом серіалізації загального призначення. Цей клас (і відповідний API Parcelable для розміщення довільних об'єктів у посилці) розроблений як високоефективний транспорт IPC. Таким чином, недоцільно розміщувати будь-які дані посилок для постійного зберігання: зміни в базовій реалізації будь-якого з даних у посилці можуть зробити старі дані нечитабельними.
Маркос Васконцелос

0

Загальні спільні переваги (CURD) SharedPreference: зберігати дані у вигляді пар значень-ключів з простим класом Котліна.

var sp = SharedPreference(this);

Зберігання даних:

Для зберігання даних String, Int і Boolean у нас є три методи з однаковою назвою та різними параметрами (Метод перевантаження).

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)

Очистити всі дані: Щоб очистити всі параметри спільного користування, використовуйте наведений нижче код.

 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.