Android - SharedPreferences with serializable object

前端 未结 6 1682
死守一世寂寞
死守一世寂寞 2020-11-29 01:55

I know that SharedPreferences has putString(), putFloat(), putLong(), putInt() and putBoolean(). But I need

相关标签:
6条回答
  • 2020-11-29 02:19

    It is possible to do it without a file.

    I'm serializing the information to base64 and like this I'm able to save it as a string in the preferences.

    The following code is Serializing a serializable objec to base64 string and vice versa: import android.util.Base64;

    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    
    
    public class ObjectSerializerHelper {
        static public String objectToString(Serializable 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;
        }
    
        @SuppressWarnings("unchecked")
        static public Serializable stringToObject(String string){
            byte[] bytes = Base64.decode(string,0);
            Serializable object = null;
            try {
                ObjectInputStream objectInputStream = new ObjectInputStream( new ByteArrayInputStream(bytes) );
                object = (Serializable)objectInputStream.readObject();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (ClassCastException e) {
                e.printStackTrace();
            }
            return object;
        }
    
    }
    
    0 讨论(0)
  • 2020-11-29 02:20

    2020: If you want to save objects, then it's better to use Proto DataStore instead of SharedPreferences.

    It brings great benefits over the “old” SharedPreferences, namely:

    • Async API for storing and reading the data (Flow)
    • Type-safety out of the box (Protocol Buffers)
    • Safe to call from UI thread (Dispatchers.IO underneath)

    And many other perks such as transactional API, which guarantee consistency.

    Check out my blog post to see how to implement Proto DataStore easily

    0 讨论(0)
  • 2020-11-29 02:25

    The accepted answer is misleading, we can store serializable object into SharedPreferences by using GSON. Read more about it at google-gson.

    you can add GSON dependency in Gradle file with:

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

    Here the snippet:

    First, create your usual sharedPreferences:

    //Creating a shared preference
    SharedPreferences  mPrefs = getPreferences(MODE_PRIVATE);
    

    Saving from serializable object to preference:

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

    Get serializable object from preference:

    Gson gson = new Gson();
    String json = mPrefs.getString("SerializableObject", "");
    yourSerializableObject = gson.fromJson(json, YourSerializableObject.class);
    
    0 讨论(0)
  • 2020-11-29 02:27

    We can create an easy to use syntax with Kotlin.

    @Throws(JsonIOException::class)
    fun Serializable.toJson(): String {
       return Gson().toJson(this)
    }
    
    @Throws(JsonSyntaxException::class)
     fun <T> String.to(type: Class<T>): T where T : Serializable {
     return Gson().fromJson(this, type)
    }
    
    @Throws(JsonIOException::class)
    fun SharedPreferences.Editor.putSerializable(key: String, o: Serializable?) = apply {
       putString(key, o?.toJson())
    }
    
    @Throws(JsonSyntaxException::class)
       fun <T> SharedPreferences.getSerializable(key: String, type: Class<T>): T? where T : Serializable {
        return getString(key, null)?.to(type)
    }
    

    and then save any Serializable to SharedPreferences using similar get/put()

    Complete gist here Save Serializables in Shared Preferences with Kotlin and GSON

    As mentioned in other answers, you might have to consider migration when structure of data class changes. Or atleast would have to change key that you use to store.

    0 讨论(0)
  • 2020-11-29 02:30

    In short you cant, try serializing your object to a private file, it amounts to the same thing. sample class below:

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    
    import android.app.Activity;
    import android.content.Context;
    
    /**
     *
     * Writes/reads an object to/from a private local file
     * 
     *
     */
    public class LocalPersistence {
    
    
        /**
         * 
         * @param context
         * @param object
         * @param filename
         */
        public static void witeObjectToFile(Context context, Object object, String filename) {
    
            ObjectOutputStream objectOut = null;
            try {
    
                FileOutputStream fileOut = context.openFileOutput(filename, Activity.MODE_PRIVATE);
                objectOut = new ObjectOutputStream(fileOut);
                objectOut.writeObject(object);
                fileOut.getFD().sync();
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (objectOut != null) {
                    try {
                        objectOut.close();
                    } catch (IOException e) {
                        // do nowt
                    }
                }
            }
        }
    
    
        /**
         * 
         * @param context
         * @param filename
         * @return
         */
        public static Object readObjectFromFile(Context context, String filename) {
    
            ObjectInputStream objectIn = null;
            Object object = null;
            try {
    
                FileInputStream fileIn = context.getApplicationContext().openFileInput(filename);
                objectIn = new ObjectInputStream(fileIn);
                object = objectIn.readObject();
    
            } catch (FileNotFoundException e) {
                // Do nothing
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } finally {
                if (objectIn != null) {
                    try {
                        objectIn.close();
                    } catch (IOException e) {
                        // do nowt
                    }
                }
            }
    
            return object;
        }
    
    }
    
    0 讨论(0)
  • 2020-11-29 02:32

    If you object is simple POJO you can convert object to JSON string and save it in shared preferences with putString().

    0 讨论(0)
提交回复
热议问题