代码审查最好的方法使用SharedPreferences解决MemoryLeak

我尝试解决共享偏好使用中的内存泄漏,我整天尝试这样做,但仍然混淆,我的目标是可能调用pref在任何我想要的。 在这里我的代码。

class Preferences (private val context: Context) { private val sharedPreferences: SharedPreferences = context.getSharedPreferences(context.packageName+"_pref", Context.MODE_PRIVATE) private val editor: SharedPreferences.Editor companion object { private val KEY_USER = "user" private val KEY_EMAIL = "email" } init { editor = sharedPreferences.edit() } private fun isKeyExist(Key: String): Boolean = sharedPreferences.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 = sharedPreferences.getInt(Key, 0) private fun getString(Key: String): String = sharedPreferences.getString(Key, "") private fun getBoolean(key: String): Boolean = sharedPreferences.getBoolean(key, false) private fun getLong(key: String): Long = sharedPreferences.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) 

因为pref需要上下文,所以我在下面的一些扩展的Application类的代码中初始化一些类,

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

使用这种方法,可以像活动,片段或某些没有上下文的类一样在任何地方调用pref,用这种简单的方法,

 BaseApplication.preferences!!.user 

但它会使我的应用程序内存泄漏。 如果有人可以给我一些建议如何解决内存泄漏,将不胜感激。

我们把这个用法称为单例模式。 使用这个类:

 public class Prefs { private static final String TAG = "Prefs"; static Prefs singleton = null; static SharedPreferences preferences; static SharedPreferences.Editor editor; private static Gson GSON = new Gson(); Type typeOfObject = new TypeToken() { }.getType(); Prefs(Context context) { preferences = context.getSharedPreferences(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 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 getObject(String key, Class 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 getStringSet(String key, Set defValue) { return preferences.getStringSet(key, defValue); } public Map 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); } } } 

kotlin版本:

 class Prefs internal constructor(context: Context) { internal var typeOfObject = object : TypeToken() { }.type val all: Map get() = preferences.all init { preferences = context.getSharedPreferences(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) { 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  getObject(key: String, a: Class): 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): Set? { 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: SharedPreferences lateinit var editor: SharedPreferences.Editor private val GSON = Gson() fun with(context: Context): Prefs { if (singleton == null) { singleton = Builder(context).build() } return singleton } } } 

您将需要谷歌GSON来保存对象。 调用它是这样的:

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

希望这可以帮助。