armazenar e recuperar um objeto de classe em preferência compartilhada


111

No Android, podemos armazenar um objeto de uma classe em preferência compartilhada e recuperar o objeto mais tarde?

Se é possível como fazer? Se não for possível, quais são as outras possibilidades de fazê-lo?

Eu sei que a serialização é uma opção, mas estou procurando possibilidades usando a preferência compartilhada.




Aqui está uma resposta a uma pergunta semelhante.
— tpk


Você pode usar esta biblioteca que tem muitos recursos embutidos. github.com/moinkhan-in/PreferenceSpider
— Moinkhan

Respostas:


15

Não é possivel.

Você só pode armazenar valores simples em SharedPrefences SharePreferences.Editor

E em particular sobre a classe que você precisa salvar?


1
Obrigado. Eu quero armazenar alguns membros de dados da classe. E eu não quero armazenar cada valor de membros de dados usando preferência compartilhada. Eu quero armazená-lo como um objeto. Se não for preferência compartilhada, quais são minhas outras opções?
— androidGuy

5
Serializar e armazenar, em um banco de dados (SQLite) / em um arquivo plano.
— Blundell

5
A resposta não está completa. A solução possível é transformar o pojo em ByteArrayOutPutStream e salvar como String em
— SharedPreferences

27
outra opção é salva como json e mapeada de volta. Com GSON ou jackSON é realmente fácil
— rallat em

2
deixe-me levar minha máquina do tempo de volta a 2011 e descobrir isso
— Blundell

324

Sim, podemos fazer isso usando Gson

Baixe o código de trabalho do GitHub

SharedPreferences mPrefs = getPreferences(MODE_PRIVATE);

Para salvar

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

Esqueço

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

Update1

A versão mais recente do GSON pode ser baixada em github.com/google/gson .

Update2

Se você estiver usando o Gradle / Android Studio, basta colocar o seguinte na build.gradleseção de dependências -

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

não está funcionando no meu caso. Mesmo depois de colocar jar em libs e definir o caminho de construção, a classe Gson não foi resolvida.
— Shirish Herwade

Limpe o projeto e tente @ShirishHerwade
— Parag Chauhan

@parag que também não está funcionando. Você pode me dizer as etapas para usar esse jar para remover o erro acima. Porque eu adicionei com sucesso aquele jar na pasta libs e, em seguida, em "java build path" também tentei adicionar json de armazenamento externo em meu desktop
— Shirish Herwade

7
Essa resposta seria ainda melhor se mencionasse também suas limitações. Que tipo de objeto podemos e não podemos armazenar e recuperar dessa maneira? Obviamente, isso não funcionará para todas as classes.
— wvdz

3
String json = gson.toJson("MyObject");deve ser o objeto, não uma String.
— Ahmed Hegazy

44

podemos usar Outputstream para enviar nosso objeto para a memória interna. E converta para string e salve de preferência. Por exemplo:

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

quando precisamos extrair o objeto de preferência. Use o código abaixo

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

Olá, sei que isso foi postado há algum tempo, mas tem certeza de que o código que possui para extrair o objeto armazenado está correto? Estou recebendo vários erros nas últimas 2 linhas reclamando sobre como os construtores explícitos precisam ser definidos em vez de simplesmente ter "new ObjectInputStream (byteArray)". Obrigado pela ajuda!
— Wakka Wakka Wakka

Oi, de repente estou recebendo uma EOFException em in = new ObjectInputStream (base64InputStream); Estou escrevendo para preferências compartilhadas exatamente da mesma maneira que você. O que você acha que pode estar errado?
— marienke

Você tem alguma exceção ao escrever Object to pref? Do SDK: Lançada EOFException quando um programa encontra o final de um arquivo ou fluxo durante uma operação de entrada.
— Kislingk

Parabéns, essa é a melhor solução que encontrei para esse problema até agora. Sem dependências. No entanto, deve-se notar que para poder usar ObjectOutput / InputStream para um objeto, o referido objeto e todos os objetos personalizados dentro dele devem implementar a interface serializável.
— user1112789

8

Eu tive o mesmo problema, aqui está minha solução:

Tenho a classe MyClass e ArrayList <MyClass> que desejo salvar nas Preferências compartilhadas. A princípio, adicionei um método a MyClass que o converte em objeto 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;
}

Então aqui está o método para salvar o objeto "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();

E aqui está o método para recuperar o objeto:

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

Observe que StringSet em Preferências compartilhadas está disponível desde a API 11.


Resolveu meu problema. Eu quero adicionar algo. Para o primeiro uso, devemos verificar se o conjunto é nulo. if (set! = null) {for (String s: set) {..}}
— xevser de

@xevser Eu adicionei verificação de nulos conforme sugerido. Obrigado.
— Micer,

6

Usando a Biblioteca Gson:

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

Loja:

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

Recuperar:

String json = getPrefs().getUserJson();

O pacote não é um mecanismo de serialização de uso geral. Esta classe (e a API Parcelable correspondente para colocar objetos arbitrários em um Parcel) é projetada como um transporte IPC de alto desempenho. Como tal, não é apropriado colocar quaisquer dados do Parcel no armazenamento persistente: as alterações na implementação subjacente de qualquer um dos dados do Parcel podem tornar os dados mais antigos ilegíveis.
— Marcos Vasconcelos

1

Você pode fazer isso usando a PowerPreferencebiblioteca em 3 etapas fáceis!

https://github.com/AliAsadi/PowerPreference

1. Criar objeto

Object obj = new Object();

2. Escreva de acordo com a preferência compartilhada

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

3. Obtendo o objeto

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

0

Usando este objeto -> TinyDB - Android-Shared-Preferences-Turbo é muito simples. você pode salvar a maioria dos objetos comumente usados ​​com ele, como matrizes, inteiros, listas de strings, etc.


Legal, mas acho que isso funciona apenas para tipos primitivos (String, double, int, etc) e não para objetos personalizados (POJOS)
— CommonSenseCode

agora funciona para objetos personalizados, verifique o Leia-me, ele foi atualizado
— kc ochibili

0

Você pode usar a biblioteca Complex Preferences Android - de Felipe Silvestre para armazenar seus objetos personalizados. Basicamente, ele está usando o mecanismo GSON para armazenar objetos.

Para salvar o objeto em preferências:

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

E para recuperá-lo:

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

O pacote não é um mecanismo de serialização de uso geral. Esta classe (e a API Parcelable correspondente para colocar objetos arbitrários em um Parcel) é projetada como um transporte IPC de alto desempenho. Como tal, não é apropriado colocar quaisquer dados do Parcel no armazenamento persistente: as alterações na implementação subjacente de qualquer um dos dados do Parcel podem tornar os dados mais antigos ilegíveis.
— Marcos Vasconcelos

Esta é obsoleto
— IgorGanapolsky

0

Você pode usar GSON, usando Gradle Build.gradle:

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

Então, em seu código, por exemplo, pares de string / booleano com Kotlin:

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

Adicionando a SharedPrefs:

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

Agora, para recuperar os dados:

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

O pacote não é um mecanismo de serialização de uso geral. Esta classe (e a API Parcelable correspondente para colocar objetos arbitrários em um Parcel) é projetada como um transporte IPC de alto desempenho. Como tal, não é apropriado colocar quaisquer dados do Parcel no armazenamento persistente: as alterações na implementação subjacente de qualquer um dos dados do Parcel podem tornar os dados mais antigos ilegíveis.
— Marcos Vasconcelos

0

Preferência comum compartilhada (CURD) SharedPreference: para armazenar dados na forma de pares de valor-chave com uma classe Kotlin simples.

var sp = SharedPreference(this);

Armazenamento de dados:

Para armazenar dados String, Int e Boolean, temos três métodos com o mesmo nome e parâmetros diferentes (Sobrecarga de método).

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

Recuperar dados: Para recuperar os dados armazenados em SharedPreferences, use os seguintes métodos.

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

Limpar todos os dados: para limpar todas as SharedPreferences, use o código a seguir.

 sp.clearSharedPreference()

Remova dados específicos:

sp.removeValue("user_name")

Classe de preferência compartilhada comum

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


-2

Não há como armazenar objetos em SharedPreferences. O que fiz foi criar uma classe pública, colocar todos os parâmetros que preciso e criar setters e getters, consegui acessar meus objetos,


-3

Você precisa recuperar o objeto mesmo após o aplicativo fechar o donw ou apenas durante sua execução?

Você pode armazená-lo em um banco de dados.
Ou simplesmente crie uma classe de aplicativo personalizada.

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>

E então, em todas as atividades, faça:

((MyApplication) getApplication).getMyObject();

Não é realmente a melhor maneira, mas funciona.


-6

Sim. Você pode armazenar e recuperar o objeto usando Sharedpreference

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.