Revisión de código La mejor manera de uso ShanetworkingPreferences solving MemoryLeak

Intento resolver la fuga de memory en el uso de Preferences Compartidas, lo bash todo el día para hacer esto, pero todavía confundo, mi objective es llamar a la opción de pref en cualquier lugar que desee. aquí mi código

class Preferences (private val context: Context) { private val shanetworkingPreferences: ShanetworkingPreferences = context.getShanetworkingPreferences(context.packageName+"_pref", Context.MODE_PRIVATE) private val editor: ShanetworkingPreferences.Editor companion object { private val KEY_USER = "user" private val KEY_EMAIL = "email" } init { editor = shanetworkingPreferences.edit() } private fun isKeyExist(Key: String): Boolean = shanetworkingPreferences.contains(Key) private fun putString(Key: String, value: String) { editor.putString(Key, value) editor.apply() } private fun putInt(Key: String, value: Int) { editor.putInt(Key, value) editor.apply() } private fun putBoolean(Key: String, value: Boolean) { editor.putBoolean(Key, value) editor.apply() } private fun putDouble(key: String, value: Double) { editor.putLong(key, java.lang.Double.doubleToRawLongBits(value)) } private fun getInt(Key: String): Int = shanetworkingPreferences.getInt(Key, 0) private fun getString(Key: String): String = shanetworkingPreferences.getString(Key, "") private fun getBoolean(key: String): Boolean = shanetworkingPreferences.getBoolean(key, false) private fun getLong(key: String): Long = shanetworkingPreferences.getLong(key, 0) fun init (){ if(!isKeyExist(KEY_USER)){ putString(KEY_USER,"") } if(!isKeyExist(KEY_EMAIL)){ putString(KEY_EMAIL,"") } } private fun resetPref(){ if(isKeyExist(KEY_USER)){ putString(KEY_USER,"") } if(isKeyExist(KEY_EMAIL)){ putString(KEY_EMAIL,"") } } var user : String get() = getString(KEY_USER) set(value) = putString(KEY_USER,value) var email : String get() = getString(KEY_EMAIL) set(value) = putString(KEY_EMAIL,value) 

Debido a que pref necesita context, inicie pref en alguna class con extensión Aplicación como código a continuación,

 class BaseApplication : android.app.Application() { override fun onCreate() { super.onCreate() preferences = Preferences(applicationContext) } companion object { @SuppressLint("StaticFieldLeak") var preferences : Preferences? = null } 

con este método, es posible llamar a pref en cualquier lugar como actividad, fragment o alguna class sin context, de esta manera simple,

 BaseApplication.preferences!!.user 

pero hará que la memory se escape en mis aplicaciones. apreciaré si alguien me puede dar algunos consejos sobre cómo resolver la fuga de memory.

    Llamamos a este uso como un patrón único. Use esta class:

     public class Prefs { private static final String TAG = "Prefs"; static Prefs singleton = null; static ShanetworkingPreferences preferences; static ShanetworkingPreferences.Editor editor; private static Gson GSON = new Gson(); Type typeOfObject = new TypeToken<Object>() { }.getType(); Prefs(Context context) { preferences = context.getShanetworkingPreferences(TAG, Context.MODE_PRIVATE); editor = preferences.edit(); } public static Prefs with(Context context) { if (singleton == null) { singleton = new Builder(context).build(); } return singleton; } public void save(String key, boolean value) { editor.putBoolean(key, value).apply(); } public void save(String key, String value) { editor.putString(key, value).apply(); } public void save(String key, int value) { editor.putInt(key, value).apply(); } public void save(String key, float value) { editor.putFloat(key, value).apply(); } public void save(String key, long value) { editor.putLong(key, value).apply(); } public void save(String key, Set<String> value) { editor.putStringSet(key, value).apply(); } // to save object in prefrence public void save(String key, Object object) { if (object == null) { throw new IllegalArgumentException("object is null"); } if (key.equals("") || key == null) { throw new IllegalArgumentException("key is empty or null"); } editor.putString(key, GSON.toJson(object)).apply(); } // To get object from prefrences public <T> T getObject(String key, Class<T> a) { String gson = preferences.getString(key, null); if (gson == null) { return null; } else { try { return GSON.fromJson(gson, a); } catch (Exception e) { throw new IllegalArgumentException("Object storaged with key " + key + " is instanceof other class"); } } } public boolean getBoolean(String key, boolean defValue) { return preferences.getBoolean(key, defValue); } public String getString(String key, String defValue) { return preferences.getString(key, defValue); } public int getInt(String key, int defValue) { return preferences.getInt(key, defValue); } public float getFloat(String key, float defValue) { return preferences.getFloat(key, defValue); } public long getLong(String key, long defValue) { return preferences.getLong(key, defValue); } public Set<String> getStringSet(String key, Set<String> defValue) { return preferences.getStringSet(key, defValue); } public Map<String, ?> getAll() { return preferences.getAll(); } public void remove(String key) { editor.remove(key).apply(); } public void removeAll() { editor.clear(); editor.apply(); } private static class Builder { private final Context context; public Builder(Context context) { if (context == null) { throw new IllegalArgumentException("Context must not be null."); } this.context = context.getApplicationContext(); } /** * Method that creates an instance of Prefs * * @return an instance of Prefs */ public Prefs build() { return new Prefs(context); } } } 

    La versión de kotlin:

     class Prefs internal constructor(context: Context) { internal var typeOfObject = object : TypeToken<Any>() { }.type val all: Map<String, *> get() = preferences.all init { preferences = context.getShanetworkingPreferences(TAG, Context.MODE_PRIVATE) editor = preferences.edit() } fun save(key: String, value: Boolean) { editor.putBoolean(key, value).apply() } fun save(key: String, value: String) { editor.putString(key, value).apply() } fun save(key: String, value: Int) { editor.putInt(key, value).apply() } fun save(key: String, value: Float) { editor.putFloat(key, value).apply() } fun save(key: String, value: Long) { editor.putLong(key, value).apply() } fun save(key: String, value: Set<String>) { editor.putStringSet(key, value).apply() } // to save object in prefrence fun save(key: String?, `object`: Any?) { if (`object` == null) { throw IllegalArgumentException("object is null") } if (key == "" || key == null) { throw IllegalArgumentException("key is empty or null") } editor.putString(key, GSON.toJson(`object`)).apply() } // To get object from prefrences fun <T> getObject(key: String, a: Class<T>): T? { val gson = preferences.getString(key, null) return if (gson == null) { null } else { try { GSON.fromJson(gson, a) } catch (e: Exception) { throw IllegalArgumentException("Object storaged with key " + key + " is instanceof other class") } } } fun getBoolean(key: String, defValue: Boolean): Boolean { return preferences.getBoolean(key, defValue) } fun getString(key: String, defValue: String): String? { return preferences.getString(key, defValue) } fun getInt(key: String, defValue: Int): Int { return preferences.getInt(key, defValue) } fun getFloat(key: String, defValue: Float): Float { return preferences.getFloat(key, defValue) } fun getLong(key: String, defValue: Long): Long { return preferences.getLong(key, defValue) } fun getStringSet(key: String, defValue: Set<String>): Set<String>? { return preferences.getStringSet(key, defValue) } fun remove(key: String) { editor.remove(key).apply() } fun removeAll() { editor.clear() editor.apply() } private class Builder(context: Context?) { private val context: Context init { if (context == null) { throw IllegalArgumentException("Context must not be null.") } this.context = context.applicationContext } /** * Method that creates an instance of Prefs * * @return an instance of Prefs */ fun build(): Prefs { return Prefs(context) } } companion object { private val TAG = "Prefs" lateinit var singleton: Prefs lateinit var preferences: ShanetworkingPreferences lateinit var editor: ShanetworkingPreferences.Editor private val GSON = Gson() fun with(context: Context): Prefs { if (singleton == null) { singleton = Builder(context).build() } return singleton } } } 

    Necesitarás google GSON para save objects. Llamarlo es así:

     Prefs.with(context).save("key","value or object or int or boolean"); 

    Espero que esto ayude.