Como o Android SharedPreferences salva / armazena objetos

214

Precisamos obter objetos de usuário em muitos lugares, que contêm muitos campos. Após o login, desejo salvar / armazenar esses objetos de usuário. Como podemos implementar esse tipo de cenário?

Não posso armazená-lo assim:

SharedPreferences.Editor prefsEditor = myPrefs.edit();
prefsEditor.putString("BusinessUnit", strBusinessUnit);
Piraba
fonte
que tipo de dados você deseja armazenar?
Ilango j
O que você quis dizer com ~ " e Objeto executivo "? Verifique sua gramática antes de postar no StackOverflow.
IgorGanapolsky
Você pode usar esta biblioteca que possui muitos recursos ... github.com/moinkhan-in/PreferenceSpider
Moinkhan

Respostas:

547

Você pode usar o gson.jar para armazenar objetos de classe em SharedPreferences . Você pode baixar este jar no google-gson

Ou adicione a dependência do GSON no seu arquivo Gradle:

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

Criando uma preferência compartilhada:

SharedPreferences  mPrefs = getPreferences(MODE_PRIVATE);

Salvar:

MyObject myObject = new MyObject;
//set variables of 'myObject', etc.

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

Para recuperar:

Gson gson = new Gson();
String json = mPrefs.getString("MyObject", "");
MyObject obj = gson.fromJson(json, MyObject.class);
Muhammad Aamir Ali
fonte
9
Valeu amigo! Mas você está incorreto na parte Salvar (linha 3), o código correto é: String json = gson.toJson (myObject);
Cesarferreira
Você precisa de todos os 3 frascos? Existem 3 deles nesse link. . .
Coolcool1994
3
O URL correto para baixar o jar é: search.maven.org/…
Shajeel Afzal
2
Isto tem um problema com referência circular que leva a StackOverflowException xD Leia mais aqui stackoverflow.com/questions/10209959/...
phuwin
1
@rozina sim Gson é melhor. Antes de tudo, para usar serializar, o objeto e todos os objetos dentro dele precisam implementar a interface de serialização. Isso não é necessário para o gson. O gson também funciona muito bem quando seu objeto é uma lista de objetos.
Neville Nazerane
36

Para adicionar à resposta de @ MuhammadAamirALi, você pode usar o Gson para salvar e recuperar uma lista de objetos

Salvar lista de objetos definidos pelo usuário em SharedPreferences

public static final String KEY_CONNECTIONS = "KEY_CONNECTIONS";
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();

User entity = new User();
// ... set entity fields

List<Connection> connections = entity.getConnections();
// convert java object to JSON format,
// and returned as JSON formatted string
String connectionsJSONString = new Gson().toJson(connections);
editor.putString(KEY_CONNECTIONS, connectionsJSONString);
editor.commit();

Obter Lista de objetos definidos pelo usuário em SharedPreferences

String connectionsJSONString = getPreferences(MODE_PRIVATE).getString(KEY_CONNECTIONS, null);
Type type = new TypeToken < List < Connection >> () {}.getType();
List < Connection > connections = new Gson().fromJson(connectionsJSONString, type);
toobsco42
fonte
3
O que é "Tipo" lá? (na lista Obter, segunda linha).
gangadhars
15

Eu sei que esta discussão é um pouco antiga. Mas vou postar isso de qualquer maneira, esperando que ajude alguém. Podemos armazenar campos de qualquer objeto com preferência compartilhada serializando o objeto para String. Aqui eu usei GSONpara armazenar qualquer objeto de preferência compartilhada.

Salvar objeto como preferência:

public static void saveObjectToSharedPreference(Context context, String preferenceFileName, String serializedObjectKey, Object object) {
    SharedPreferences sharedPreferences = context.getSharedPreferences(preferenceFileName, 0);
    SharedPreferences.Editor sharedPreferencesEditor = sharedPreferences.edit();
    final Gson gson = new Gson();
    String serializedObject = gson.toJson(object);
    sharedPreferencesEditor.putString(serializedObjectKey, serializedObject);
    sharedPreferencesEditor.apply();
}

Recuperar objeto de preferência:

public static <GenericClass> GenericClass getSavedObjectFromPreference(Context context, String preferenceFileName, String preferenceKey, Class<GenericClass> classType) {
    SharedPreferences sharedPreferences = context.getSharedPreferences(preferenceFileName, 0);
    if (sharedPreferences.contains(preferenceKey)) {
        final Gson gson = new Gson();
        return gson.fromJson(sharedPreferences.getString(preferenceKey, ""), classType);
    }
    return null;
}

Nota :

Lembre-se de adicionar compile 'com.google.code.gson:gson:2.6.2'ao dependenciesseu gradle.

Exemplo :

//assume SampleClass exists
SampleClass mObject = new SampleObject();

//to store an object
saveObjectToSharedPreference(context, "mPreference", "mObjectKey", mObject);

//to retrive object stored in preference
mObject = getSavedObjectFromPreference(context, "mPreference", "mObjectKey", SampleClass.class);

Atualizar:

Como o @Sharp_Edge apontou nos comentários, a solução acima não funciona List.

Uma pequena modificação na assinatura de getSavedObjectFromPreference()- from Class<GenericClass> classTypepara Type classTypefará com que essa solução seja generalizada. Assinatura de função modificada,

public static <GenericClass> GenericClass getSavedObjectFromPreference(Context context, String preferenceFileName, String preferenceKey, Type classType)

Para invocar,

getSavedObjectFromPreference(context, "mPreference", "mObjectKey", (Type) SampleClass.class)

Feliz codificação!

tpk
fonte
1
isso foi realmente útil obrigado. Para alguém aqui que queira comentar ... devo ligar para saveObjectToSharedPreference em onSaveInstanceState? Eu já o tenho no onSaveInstanceState, mas, como meu aplicativo está coletando dados em tempo real a cada 10 segundos, recebo um soluço de vez em quando e o objeto que estou salvando com saveObjectToSharedPreference perde algumas leituras. Todos os pensamentos são bem-vindos.
Frank Zappa
ei @FrankZappa, perdoe-me por não entender completamente o seu problema, mas aqui está, tente usar em commitvez de apply. Isso pode ajudá-lo.
tpk
obrigado. Deixe-me tentar explicar. Meu aplicativo Android coleta dados em tempo real aproximadamente a cada 10 segundos. Essa coleta de dados não usa objetos, apenas variáveis ​​globais e lógica. Em seguida, os dados são resumidos e armazenados em um objeto Java. Uso o método acima para armazenar e recuperar meu objeto Java em / via SharedPreferences porque: a) que eu saiba, não posso armazenar objetos em onSavedInstanceState eb) quando a tela gira, meu objeto é destruído e recriado. Portanto, estou usando sua abordagem SharedPrefs; portanto, quando a tela é girada, meu objeto não perde seus valores. (cont ..)
Frank Zappa
Coloquei sua rotina saveObjectToSharedPreferences em onSaveInstanceState. Coloquei sua rotina getSavedObjectFromPreference em onRestoreInstanceState. No entanto, testei e ainda recebi um conjunto de atualizações de objetos perdidos devido à rotação da tela. Portanto, devo mover a chamada para saveObjectToSharedPreferences para mais perto da minha lógica real? Por fim, a que método se refere e se aplica?
Frank Zappa
1
@ 2943 Sua solução parece ótima, mas se eu tiver uma lista, por exemplo, List<CustomClass>como devo fazer isso? getSavedObjectFromPreference(context, "mPreference", "mObjectKey", SampleClass.class)não está aceitando List<CustomClass>.class:(
Sharp Edge
6

Melhor é criar uma Constantsclasse global para salvar chaves ou variáveis ​​para buscar ou salvar dados.

Para salvar dados, chame esse método para salvar dados de todos os lugares.

public static void saveData(Context con, String variable, String data)
{
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(con);
    prefs.edit().putString(variable, data).commit();
}

Use-o para obter dados.

public static String getData(Context con, String variable, String defaultValue)
{
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(con);
    String data = prefs.getString(variable, defaultValue);
    return data;
}

e um método parecido com isto fará o truque

public static User getUserInfo(Context con)
{
    String id =  getData(con, Constants.USER_ID, null);
    String name =  getData(con, Constants.USER_NAME, null);
    if(id != null && name != null)
    {
            User user = new User(); //Hope you will have a user Object.
            user.setId(id);
            user.setName(name);
            //Here set other credentials.
            return user;
    }
    else
    return null;
}
Adil Soomro
fonte
Para recuperar os dados, o que passo como 'variável' e 'defaultValue'?
Alex
Nunca crie uma classe Constantes. Isso torna seu código altamente acoplado e disperso ao mesmo tempo.
11138 Miha_x64
5

Tente da melhor maneira:

PreferenceConnector.java

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class PreferenceConnector {
    public static final String PREF_NAME = "ENUMERATOR_PREFERENCES";
    public static final String PREF_NAME_REMEMBER = "ENUMERATOR_REMEMBER";
    public static final int MODE = Context.MODE_PRIVATE;


    public static final String name = "name";


    public static void writeBoolean(Context context, String key, boolean value) {
        getEditor(context).putBoolean(key, value).commit();
    }

    public static boolean readBoolean(Context context, String key,
            boolean defValue) {
        return getPreferences(context).getBoolean(key, defValue);
    }

    public static void writeInteger(Context context, String key, int value) {
        getEditor(context).putInt(key, value).commit();

    }

    public static int readInteger(Context context, String key, int defValue) {
        return getPreferences(context).getInt(key, defValue);
    }

    public static void writeString(Context context, String key, String value) {
        getEditor(context).putString(key, value).commit();

    }

    public static String readString(Context context, String key, String defValue) {
        return getPreferences(context).getString(key, defValue);
    }

    public static void writeLong(Context context, String key, long value) {
        getEditor(context).putLong(key, value).commit();
    }

    public static long readLong(Context context, String key, long defValue) {
        return getPreferences(context).getLong(key, defValue);
    }

    public static SharedPreferences getPreferences(Context context) {
        return context.getSharedPreferences(PREF_NAME, MODE);
    }

    public static Editor getEditor(Context context) {
        return getPreferences(context).edit();
    }

}

Escreva o valor:

PreferenceConnector.writeString(this, PreferenceConnector.name,"Girish");

E obtenha valor usando:

String name= PreferenceConnector.readString(this, PreferenceConnector.name, "");
Girish Patel
fonte
2
O que isso tem a ver com salvar um objeto em SharedPreferences no Android?
IgorGanapolsky
Mais informações sobre como trabalhar com preferências compartilhadas podem ser encontradas em stackoverflow.com/a/2614771/1815624 observação que você pode querer usar em return PreferenceManager.getDefaultSharedPreferences(context);vez dereturn context.getSharedPreferences(PREF_NAME, MODE);
CrandellWS
3

Você não declarou o que faz com o prefsEditorobjeto depois disso, mas para manter os dados de preferência, você também precisa usar:

prefsEditor.commit();
RivieraKid
fonte
2

Veja aqui, isso pode ajudá-lo:

public static boolean setObject(Context context, Object o) {
        Field[] fields = o.getClass().getFields();
        SharedPreferences sp = context.getSharedPreferences(o.getClass()
                .getName(), Context.MODE_PRIVATE);
        Editor editor = sp.edit();
        for (int i = 0; i < fields.length; i++) {
            Class<?> type = fields[i].getType();
            if (isSingle(type)) {
                try {
                    final String name = fields[i].getName();
                    if (type == Character.TYPE || type.equals(String.class)) {
                        Object value = fields[i].get(o);
                        if (null != value)
                            editor.putString(name, value.toString());
                    } else if (type.equals(int.class)
                            || type.equals(Short.class))
                        editor.putInt(name, fields[i].getInt(o));
                    else if (type.equals(double.class))
                        editor.putFloat(name, (float) fields[i].getDouble(o));
                    else if (type.equals(float.class))
                        editor.putFloat(name, fields[i].getFloat(o));
                    else if (type.equals(long.class))
                        editor.putLong(name, fields[i].getLong(o));
                    else if (type.equals(Boolean.class))
                        editor.putBoolean(name, fields[i].getBoolean(o));

                } catch (IllegalAccessException e) {
                    LogUtils.e(TAG, e);
                } catch (IllegalArgumentException e) {
                    LogUtils.e(TAG, e);
                }
            } else {
                // FIXME 是对象则不写入
            }
        }

        return editor.commit();
    }

https://github.com/AltasT/PreferenceVObjectFile/blob/master/PreferenceVObjectFile/src/com/altas/lib/PreferenceUtils.java

Altas
fonte
2
Você poderia explicar um pouco mais o código, pois atualmente representa apenas "um monte de código".
Werner
1

Outra maneira de salvar e restaurar um objeto das preferências compartilhadas do Android sem usar o formato Json

private static ExampleObject getObject(Context c,String db_name){
            SharedPreferences sharedPreferences = c.getSharedPreferences(db_name, Context.MODE_PRIVATE);
            ExampleObject o = new ExampleObject();
            Field[] fields = o.getClass().getFields();
            try {
                for (Field field : fields) {
                    Class<?> type = field.getType();
                    try {
                        final String name = field.getName();
                        if (type == Character.TYPE || type.equals(String.class)) {
                            field.set(o,sharedPreferences.getString(name, ""));
                        } else if (type.equals(int.class) || type.equals(Short.class))
                            field.setInt(o,sharedPreferences.getInt(name, 0));
                        else if (type.equals(double.class))
                            field.setDouble(o,sharedPreferences.getFloat(name, 0));
                        else if (type.equals(float.class))
                            field.setFloat(o,sharedPreferences.getFloat(name, 0));
                        else if (type.equals(long.class))
                            field.setLong(o,sharedPreferences.getLong(name, 0));
                        else if (type.equals(Boolean.class))
                            field.setBoolean(o,sharedPreferences.getBoolean(name, false));
                        else if (type.equals(UUID.class))
                            field.set(
                                    o,
                                    UUID.fromString(
                                            sharedPreferences.getString(
                                                    name,
                                                    UUID.nameUUIDFromBytes("".getBytes()).toString()
                                            )
                                    )
                            );

                    } catch (IllegalAccessException e) {
                        Log.e(StaticConfig.app_name, "IllegalAccessException", e);
                    } catch (IllegalArgumentException e) {
                        Log.e(StaticConfig.app_name, "IllegalArgumentException", e);
                    }
                }
            } catch (Exception e) {
                System.out.println("Exception: " + e);
            }
            return o;
        }
        private static void setObject(Context context, Object o, String db_name) {
            Field[] fields = o.getClass().getFields();
            SharedPreferences sp = context.getSharedPreferences(db_name, Context.MODE_PRIVATE);
            SharedPreferences.Editor editor = sp.edit();
            for (Field field : fields) {
                Class<?> type = field.getType();
                try {
                    final String name = field.getName();
                    if (type == Character.TYPE || type.equals(String.class)) {
                        Object value = field.get(o);
                        if (value != null)
                            editor.putString(name, value.toString());
                    } else if (type.equals(int.class) || type.equals(Short.class))
                        editor.putInt(name, field.getInt(o));
                    else if (type.equals(double.class))
                        editor.putFloat(name, (float) field.getDouble(o));
                    else if (type.equals(float.class))
                        editor.putFloat(name, field.getFloat(o));
                    else if (type.equals(long.class))
                        editor.putLong(name, field.getLong(o));
                    else if (type.equals(Boolean.class))
                        editor.putBoolean(name, field.getBoolean(o));
                    else if (type.equals(UUID.class))
                        editor.putString(name, field.get(o).toString());

                } catch (IllegalAccessException e) {
                    Log.e(StaticConfig.app_name, "IllegalAccessException", e);
                } catch (IllegalArgumentException e) {
                    Log.e(StaticConfig.app_name, "IllegalArgumentException", e);
                }
            }

            editor.apply();
        }
William Desportes
fonte
1

Você pode salvar o objeto nas preferências sem usar nenhuma biblioteca. Primeiro, sua classe de objeto deve implementar Serializable:

public class callModel implements Serializable {

private long pointTime;
private boolean callisConnected;

public callModel(boolean callisConnected,  long pointTime) {
    this.callisConnected = callisConnected;
    this.pointTime = pointTime;
}
public boolean isCallisConnected() {
    return callisConnected;
}
public long getPointTime() {
    return pointTime;
}

}

Em seguida, você pode facilmente usar esses dois métodos para converter objeto em string e string em objeto:

 public static <T extends Serializable> T stringToObjectS(String string) {
    byte[] bytes = Base64.decode(string, 0);
    T object = null;
    try {
        ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(bytes));
        object = (T) objectInputStream.readObject();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return object;
}

 public static String objectToString(Parcelable object) {
    String encoded = null;
    try {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(object);
        objectOutputStream.close();
        encoded = new String(Base64.encodeToString(byteArrayOutputStream.toByteArray(), 0));
    } catch (IOException e) {
        e.printStackTrace();
    }
    return encoded;
}

Salvar:

SharedPreferences  mPrefs = getPreferences(MODE_PRIVATE);
Editor prefsEditor = mPrefs.edit();
prefsEditor.putString("MyObject", objectToString(callModelObject));
prefsEditor.commit();

Ler

String value= mPrefs.getString("MyObject", "");
MyObject obj = stringToObjectS(value);
farhad.kargaran
fonte
Você pode evitar a codificação Base64 e o escape de XML simplesmente escrevendo esses bytes em um arquivo separado.
11138 Miha_x64
1

Etapa 1: Copie e cole essas duas funções no seu arquivo java.

 public void setDefaults(String key, String value, Context context) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putString(key, value);
        editor.commit();
    }


    public static String getDefaults(String key, Context context) {
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        return preferences.getString(key, null);
    }

Etapa 2: para salvar o uso:

 setDefaults("key","value",this);

para recuperar o uso:

String retrieve= getDefaults("key",this);

Você pode definir diferentes preferências compartilhadas usando diferentes nomes de chave, como:

setDefaults("key1","xyz",this);

setDefaults("key2","abc",this);

setDefaults("key3","pqr",this);
Viraj Singh
fonte
1

Se você deseja armazenar todo o Objeto que obtém em resposta, ele pode ser alcançado fazendo algo como,

Primeiro, crie um método que converta seu JSON em uma string na sua classe util, como abaixo.

 public static <T> T fromJson(String jsonString, Class<T> theClass) {
    return new Gson().fromJson(jsonString, theClass);
}

Em Classe Preferências Compartilhadas, faça algo como:

 public void storeLoginResponse(yourResponseClass objName) {

    String loginJSON = UtilClass.toJson(customer);
    if (!TextUtils.isEmpty(customerJSON)) {
        editor.putString(AppConst.PREF_CUSTOMER, customerJSON);
        editor.commit();
    }
}

e crie um método para getPreferences

public Customer getCustomerDetails() {
    String customerDetail = pref.getString(AppConst.PREF_CUSTOMER, null);
    if (!TextUtils.isEmpty(customerDetail)) {
        return GSONConverter.fromJson(customerDetail, Customer.class);
    } else {
        return new Customer();
    }
}

Em seguida, basta chamar o método First quando receber resposta e o segundo quando precisar obter dados de preferências de compartilhamento, como

String token = SharedPrefHelper.get().getCustomerDetails().getAccessToken();

Isso é tudo.

Espero que ajude você.

Happy Coding();

Naresh
fonte
1

Ocorreu um problema ao usar a resposta aceita para acessar os dados de Preferências compartilhadas entre as atividades. Nessas etapas, você fornece um nome para o getSharedPreferences para acessá-lo.

Adicione a seguinte dependência no arquivo build.gradel (Module: app) em Scripts Gradle:

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

Salvar:

MyObject myObject = new MyObject;
//set variables of 'myObject', etc.

SharedPreferences mPrefs = getSharedPreferences("Name", Context.MODE_PRIVATE);

Editor prefsEditor = mPrefs.edit();
Gson gson = new Gson();
String json = gson.toJson(myObject);
prefsEditor.putString("Key", json);
prefsEditor.commit();

Para recuperar em uma atividade diferente:

SharedPreferences mPrefs = getSharedPreferences("Name", Context.MODE_PRIVATE);

Gson gson = new Gson();
String json = mPrefs.getString("Key", "");
MyObject obj = gson.fromJson(json, MyObject.class);
Ben
fonte
1
// SharedPrefHelper is a class contains the get and save sharedPrefernce data
public class SharedPrefHelper {

    // save data in sharedPrefences
    public static void setSharedOBJECT(Context context, String key, 
                                           Object value) {

        SharedPreferences sharedPreferences =  context.getSharedPreferences(
                context.getPackageName(), Context.MODE_PRIVATE);

        SharedPreferences.Editor prefsEditor = sharedPreferences.edit();
        Gson gson = new Gson();
        String json = gson.toJson(value);
        prefsEditor.putString(key, json);
        prefsEditor.apply();
    }

    // get data from sharedPrefences 
    public static Object getSharedOBJECT(Context context, String key) {

         SharedPreferences sharedPreferences = context.getSharedPreferences(
                           context.getPackageName(), Context.MODE_PRIVATE);

        Gson gson = new Gson();
        String json = sharedPreferences.getString(key, "");
        Object obj = gson.fromJson(json, Object.class);
        User objData = new Gson().fromJson(obj.toString(), User.class);
        return objData;
    }
}
// save data in your activity

User user = new User("Hussein","[email protected]","3107310890983");        
SharedPrefHelper.setSharedOBJECT(this,"your_key",user);        
User data = (User) SharedPrefHelper.getSharedOBJECT(this,"your_key");

Toast.makeText(this,data.getName()+"\n"+data.getEmail()+"\n"+data.getPhone(),Toast.LENGTH_LONG).show();
// User is the class you want to save its objects

public class User {

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    private String name,email,phone;
    public User(String name,String email,String phone){
          this.name=name;
          this.email=email;
          this.phone=phone;
    }
}
// put this in gradle

compile 'com.google.code.gson:gson:2.7'

Espero que isso ajude você :)

user7168064
fonte
1

Aqui está uma visão geral sobre o uso de propriedades delegadas do Kotlin que eu peguei aqui , mas que foi expandido e permite um mecanismo simples para obter / configurar as propriedades SharedPreference.

Para String, Int, Long, Floatou Boolean, ele usa o getter padrão SharePreference (s) e Setter (s). No entanto, para todas as outras classes de dados, ele usa o GSON para serializar para a String, para o configurador. Em seguida, desserializa para o objeto de dados, para o getter.

Semelhante a outras soluções, isso requer a adição do GSON como uma dependência no seu arquivo gradle:

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

Aqui está um exemplo de uma classe de dados simples que queremos salvar e armazenar em SharedPreferences:

data class User(val first: String, val last: String)

Aqui está a classe que implementa os delegados de propriedade:

object UserPreferenceProperty : PreferenceProperty<User>(
    key = "USER_OBJECT",
    defaultValue = User(first = "Jane", last = "Doe"),
    clazz = User::class.java)

object NullableUserPreferenceProperty : NullablePreferenceProperty<User?, User>(
    key = "NULLABLE_USER_OBJECT",
    defaultValue = null,
    clazz = User::class.java)

object FirstTimeUser : PreferenceProperty<Boolean>(
        key = "FIRST_TIME_USER",
        defaultValue = false,
        clazz = Boolean::class.java
)

sealed class PreferenceProperty<T : Any>(key: String,
                                         defaultValue: T,
                                         clazz: Class<T>) : NullablePreferenceProperty<T, T>(key, defaultValue, clazz)

@Suppress("UNCHECKED_CAST")
sealed class NullablePreferenceProperty<T : Any?, U : Any>(private val key: String,
                                                           private val defaultValue: T,
                                                           private val clazz: Class<U>) : ReadWriteProperty<Any, T> {

    override fun getValue(thisRef: Any, property: KProperty<*>): T = HandstandApplication.appContext().getPreferences()
            .run {
                when {
                    clazz.isAssignableFrom(String::class.java) -> getString(key, defaultValue as String?) as T
                    clazz.isAssignableFrom(Int::class.java) -> getInt(key, defaultValue as Int) as T
                    clazz.isAssignableFrom(Long::class.java) -> getLong(key, defaultValue as Long) as T
                    clazz.isAssignableFrom(Float::class.java) -> getFloat(key, defaultValue as Float) as T
                    clazz.isAssignableFrom(Boolean::class.java) -> getBoolean(key, defaultValue as Boolean) as T
                    else -> getObject(key, defaultValue, clazz)
                }
            }

    override fun setValue(thisRef: Any, property: KProperty<*>, value: T) = HandstandApplication.appContext().getPreferences()
            .edit()
            .apply {
                when {
                    clazz.isAssignableFrom(String::class.java) -> putString(key, value as String?) as T
                    clazz.isAssignableFrom(Int::class.java) -> putInt(key, value as Int) as T
                    clazz.isAssignableFrom(Long::class.java) -> putLong(key, value as Long) as T
                    clazz.isAssignableFrom(Float::class.java) -> putFloat(key, value as Float) as T
                    clazz.isAssignableFrom(Boolean::class.java) -> putBoolean(key, value as Boolean) as T
                    else -> putObject(key, value)
                }
            }
            .apply()

    private fun Context.getPreferences(): SharedPreferences = getSharedPreferences(APP_PREF_NAME, Context.MODE_PRIVATE)

    private fun <T, U> SharedPreferences.getObject(key: String, defValue: T, clazz: Class<U>): T =
            Gson().fromJson(getString(key, null), clazz) as T ?: defValue

    private fun <T> SharedPreferences.Editor.putObject(key: String, value: T) = putString(key, Gson().toJson(value))

    companion object {
        private const val APP_PREF_NAME = "APP_PREF"
    }
}

Nota: você não precisa atualizar nada no sealed class. As propriedades são delegadas objeto / Singleton UserPreferenceProperty, NullableUserPreferencePropertye FirstTimeUser.

Para configurar um novo objeto de dados para salvar / obter de SharedPreferences, agora é tão fácil quanto adicionar quatro linhas:

object NewPreferenceProperty : PreferenceProperty<String>(
        key = "NEW_PROPERTY",
        defaultValue = "",
        clazz = String::class.java)

Por fim, você pode ler / gravar valores em SharedPreferences usando a bypalavra-chave:

private var user: User by UserPreferenceProperty
private var nullableUser: User? by NullableUserPreferenceProperty
private var isFirstTimeUser: Boolean by 

Log.d("TAG", user) // outputs the `defaultValue` for User the first time
user = User(first = "John", last = "Doe") // saves this User to the Shared Preferences
Log.d("TAG", user) // outputs the newly retrieved User (John Doe) from Shared Preferences
Jason Grife
fonte
0

Se o seu objeto for complexo, sugiro serializá-lo / XML / JSON e salvá-lo no cartão SD. Você pode encontrar informações adicionais sobre como salvar em armazenamento externo aqui: http://developer.android.com/guide/topics/data/data-storage.html#filesExternal

trenpixster
fonte
Isso não requer uma permissão extra (cartão SD)?
Rishabh
Sim, pois você escreveria no cartão SD.
Trenpixster
1
Pela minha experiência, quanto menos permissões forem necessárias para o usuário, melhor. O cartão SD deve ser uma opção secundária, se o uso do Gson como indicado acima não for uma opção viável.
Rishabh
Sim, eu também concordo com isso; Somente se o resultado JSON for grande o suficiente, o cartão SD será uma opção. É uma troca, eu diria.
Trenpixster
0

existem dois arquivos resolvidos todo o seu problema sobre preferências compartilhadas

1) AppPersistence.java

    public class AppPersistence {
    public enum keys {
        USER_NAME, USER_ID, USER_NUMBER, USER_EMAIL, USER_ADDRESS, CITY, USER_IMAGE,
        DOB, MRG_Anniversary, COMPANY, USER_TYPE, support_phone
    }

    private static AppPersistence mAppPersistance;
    private SharedPreferences sharedPreferences;

    public static AppPersistence start(Context context) {
        if (mAppPersistance == null) {
            mAppPersistance = new AppPersistence(context);
        }
        return mAppPersistance;
    }

    private AppPersistence(Context context) {
        sharedPreferences = context.getSharedPreferences(context.getString(R.string.prefrence_file_name),
                Context.MODE_PRIVATE);
    }

    public Object get(Enum key) {
        Map<String, ?> all = sharedPreferences.getAll();
        return all.get(key.toString());
    }

    void save(Enum key, Object val) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        if (val instanceof Integer) {
            editor.putInt(key.toString(), (Integer) val);
        } else if (val instanceof String) {
            editor.putString(key.toString(), String.valueOf(val));
        } else if (val instanceof Float) {
            editor.putFloat(key.toString(), (Float) val);
        } else if (val instanceof Long) {
            editor.putLong(key.toString(), (Long) val);
        } else if (val instanceof Boolean) {
            editor.putBoolean(key.toString(), (Boolean) val);
        }
        editor.apply();
    }

    void remove(Enum key) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.remove(key.toString());
        editor.apply();
    }

    public void removeAll() {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.clear();
        editor.apply();
    }
}

2) AppPreference.java

public static void setPreference(Context context, Enum Name, String Value) {
        AppPersistence.start(context).save(Name, Value);
    }

    public static String getPreference(Context context, Enum Name) {
        return (String) AppPersistence.start(context).get(Name);
    }

    public static void removePreference(Context context, Enum Name) {
        AppPersistence.start(context).remove(Name);
    }
}

agora você pode salvar, remover ou curtir,

-Salve 

AppPreference.setPreference(context, AppPersistence.keys.USER_ID, userID);

-remover

AppPreference.removePreference(context, AppPersistence.keys.USER_ID);

-obter

 AppPreference.getPreference(context, AppPersistence.keys.USER_ID);
Gautam Surani
fonte
0

Armazenar dados no SharedPreference

SharedPreferences mprefs = getSharedPreferences(AppConstant.PREFS_NAME, MODE_PRIVATE)
mprefs.edit().putString(AppConstant.USER_ID, resUserID).apply();

fonte
0

Minha classe utils para salvar a lista em SharedPreferences

public class SharedPrefApi {
    private SharedPreferences sharedPreferences;
    private Gson gson;

    public SharedPrefApi(Context context, Gson gson) {
        this.sharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        this.gson = gson;
    } 

    ...

    public <T> void putObject(String key, T value) {
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(key, gson.toJson(value));
        editor.apply();
    }

    public <T> T getObject(String key, Class<T> clazz) {
        return gson.fromJson(getString(key, null), clazz);
    }
}

Usando

// for save
sharedPrefApi.putList(SharedPrefApi.Key.USER_LIST, userList);

// for retrieve
List<User> userList = sharedPrefApi.getList(SharedPrefApi.Key.USER_LIST, User.class);

.
Código completo dos meus utilitários // verifique usando o exemplo no código de atividade

Phan Van Linh
fonte
0

Eu usei jackson para armazenar meus objetos ( jackson ).

Adicionado a biblioteca jackson para classificar:

api 'com.fasterxml.jackson.core:jackson-core:2.9.4'
api 'com.fasterxml.jackson.core:jackson-annotations:2.9.4'
api 'com.fasterxml.jackson.core:jackson-databind:2.9.4'

Minha classe de teste:

public class Car {
    private String color;
    private String type;
    // standard getters setters
}

Objeto Java para JSON:

ObjectMapper objectMapper = new ObjectMapper();
String carAsString = objectMapper.writeValueAsString(car);

Armazene-o em preferências compartilhadas:

preferences.edit().car().put(carAsString).apply();

Restaure-o a partir de preferências compartilhadas:

ObjectMapper objectMapper = new ObjectMapper();
Car car = objectMapper.readValue(preferences.car().get(), Car.class);
Manuel Schmitzberger
fonte