我尝试解决共享首选项使用中的内存泄漏,我尝试整天做这个,但仍然混淆,我的目标是可以在任何我想要的地方调用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需要上下文,所以我在某个类中初始化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
但它会在我的应用中造成内存泄漏。 如果有人能给我一些如何解决内存泄漏的建议,我将不胜感激。
答案 0 :(得分:0)
我们将此用作单例模式。使用这个类:
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<Object>() {
}.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<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);
}
}
}
kotlin版本:
class Prefs internal constructor(context: Context) {
internal var typeOfObject = object : TypeToken<Any>() {
}.type
val all: Map<String, *>
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<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: SharedPreferences
lateinit var editor: SharedPreferences.Editor
private val GSON = Gson()
fun with(context: Context): Prefs {
if (singleton == null) {
singleton = Builder(context).build()
}
return singleton
}
}
}
您需要使用Google GSON来保存对象。 打电话是这样的:
Prefs.with(context).save("key","value or object or int or boolean");
希望这有帮助。