2016-10-14 5 views
14

Мне нужен класс, который обрабатывает мои SharedPreferences, и я придумал 3 способа сделать это, однако после некоторых исследований кажется, что большинство из них считаются «анти-шаблонами».Самый безопасный способ использования SharedPreferences

Тип 1

public final class MyPrefs { 

    private MyPrefs(){ throw new AssertionError(); } 

    public static void setFavoriteColor(Context context, String value){ 
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); 
    prefs.edit().putString("color_key", value).apply(); 
    } 

    public static void setFavoriteAnimal(Context context, String value){ 
    // ... 
    } 

    // ... 

} 

/* Usage */ 
MyPrefs.setFavoriteColor(this, "yellow"); 

// Reason why it might be considered "Bad" 
// Class is not OO, just collection of static methods. "Utility Class" 

Тип 2

public class MyPrefs { 

    private SharedPreferences mPreferences; 
    private static volatile MyPrefs sInstance; 

    public static MyPrefs getInstance(Context context){ 
    if(sInstance == null){ 
     synchronized(MyPrefs.class){ 
     if(sInstance == null){ 
      sInstance = new MyPrefs(context); 
     } 
     } 
    } 
    return sInstance; 
    } 

    private MyPrefs(Context context){ 
    mPreferences = PreferenceManager.getDefaultSharedPreferences(context); 
    } 

    public void setFavoriteColor(String value){ 
    mPreferences.edit().putString("color_key", value).apply(); 
    } 

    public void setFavoriteAnimal(Context context, String value){ 
    // ... 
    } 

    // ... 

} 

/* Usage */ 
MyPrefs myPrefs = MyPrefs.getInstance(this); 
myPrefs.setFavoriteColor("red"); 


// Reason why it might be considered "Bad" 
// Singleton's are frowned upon especially 
// in android because they can cause problems and unexpected bugs. 

Тип 3

public class MyPrefs { 

    SharedPreferences mPreferences; 

    public MyPrefs(Context context){ 
    mPreferences = PreferenceManager.getDefaultSharedPreferences(context); 
    } 

    public void setFavoriteColor(String value){ 
    mPreferences.edit().putString("color_key", value).apply(); 
    } 

    public void setFavoriteAnimal(Context context, String value){ 
    // ... 
    } 

    // ... 

} 

/* Usage */ 
MyPrefs myPrefs = new MyPrefs(this); 
myPrefs.setFavoriteColor("green"); 

// Reason why it might be considered "Bad" 
// Lots of boilerplate and must create object every 
// time you want to save a preference. 

Теперь мои предпочтения обертки, очевидно, не состоят только 2 сеттеров, у них есть много добытчиков и сеттеры, которые выполняют некоторую обработку стороны перед сохранением значений, поэтому, сохраняя и обрабатывая предпочтения в течение Основная деятельность может вызвать много грязного кода и ошибок.

Теперь какой из этих подходов не будет иметь негативного влияния на производительность/вызвать непредвиденные ошибки?

+0

это вы проблема решена? –

+0

@SumitYadav да почти все. Кажется, что все они работают и могут быть безопасными в использовании, однако некоторые (например, singleton) могут вызывать проблемы, которые необходимо решать. Я просто останусь в безопасности и использую 1 или 3. – Linxy

+0

Не используйте метод .apply(), используйте метод .commit() в отдельной теме. Причина в том, что .apply() планирует сохранение в фоновом режиме, и вы не можете быть уверены, что данные сохраняются перед другим .apply(). Это может привести к потере данных. Используйте .commit() вместо этого, скажем, в цепочке rxJava –

ответ

5

Тип 1: -

В типе 1, Вы непосредственно использовать этот class method, это один лучше ........

Тип 2: -

в типе 2, есть один Static Variable, который будет вызыватьMemoryLeakException в вашем приложении. Если вы хотите использовать тип 2, то вы сделали INSTANCE переменного нуль всякий раз, когда вы используете этот класс (это может решить проблему MemoryLeakException) .......

Тип 3: -

в типа 3, вы должны создать Heap Memory (взять Ram память для экземпляра до конца по ассортименту) Илиnew Instance класса, всякий раз, когда вы хотите использовать этот класс. Этот класс поможет, если вы должны использовать это class methods во много раз в одном Activity .......

использовать этот класс для простого использования SharePrefernce .....

public class Utility { 

    public static boolean getBoolean(Context context, String key) { 
     SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); 
     return preferences.getBoolean(key, false); 
    } 

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

    public static int getInt(Context context, String key) { 
     SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); 
     return preferences.getInt(key, -1); 
    } 


    public static void setString(Context context, String key, String value) { 
     PreferenceManager.getDefaultSharedPreferences(context).edit().putString(key, value).commit(); 
    } 

    public static void setBoolean(Context context, String key, boolean value) { 
     PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(key, value).commit(); 
    } 


} 

для установки строки ....

Utility.setString(this,"token","your token"); 

и для получения струн ...

Utility.getString(this,"token"); 

Примечание: - В этом CLAS, вы не должны создавать любыеHeap Memory OR Static Variable.

+1

Этот ответ подозрительный, потому что 1) Нет ничего плохого в сохранении статической ссылки на SharedPreferences и 2) Нет такой вещи, как 'MemoryLeakException' –

+0

Является ли это' личные статические изменчивые MyPrefs sInstance; 'variable, не вызывающий' MemoryLeakException'. Я читал много блогов, где люди, говорящие с использованием статической переменной, вызывающей «MemoryLeakException», просматривают этот http://stackoverflow.com/a/39694463/5305430. Если вам нужно больше блога, дайте мне знать? – sushildlh

+0

Я думаю, вы имеете в виду «OutOfMemoryException»? Это происходит, когда вы используете слишком много памяти, и ваше приложение не может выделить больше памяти, когда это необходимо. SharedPreferences - это уже одноэлементный объект, и сохранение статической ссылки на него не приведет к увеличению объема памяти. Вы можете найти много примеров для SO одиночных оболочек для SharedPreferences. Синглтонные ссылки являются статическими ссылками. –

2

Включите этот класс в вашем проекте и всякий раз, когда вы хотите установить что-то в SharedPreferences затем использовать функцию с помощью имени класса и параметров прохода. Ваша задача будет простой, и вам просто нужно написать одну строку кода, чтобы сохранить и получить любое значение из общего PReference.

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

public class SharedPrefManager { 

    public static SharedPreferences getSharedPref(Context mContext) { 
     SharedPreferences pref = mContext.getSharedPreferences(Constants.SETTINGS, Context.MODE_PRIVATE); 

     return pref; 
    } 

    public static void setPrefVal(Context mContext, String key, String value) { 
     if(key!=null){ 
     Editor edit = getSharedPref(mContext).edit(); 
     edit.putString(key, value); 
     edit.commit(); 
     } 
    } 

    public static void setIntPrefVal(Context mContext, String key, int value) { 
     if(key!=null){ 
      Editor edit = getSharedPref(mContext).edit(); 
      edit.putInt(key, value); 
      edit.commit(); 
     } 
    } 

    public static void setLongPrefVal(Context mContext, String key, Long value) { 
     if(key!=null){ 
      Editor edit = getSharedPref(mContext).edit(); 
      edit.putLong(key, value); 
      edit.commit(); 
     } 
    } 

    public static void setBooleanPrefVal(Context mContext, String key, boolean value) { 
     if(key!=null){ 
      Editor edit = getSharedPref(mContext).edit(); 
      edit.putBoolean(key, value); 
      edit.commit(); 
     } 
    } 


    public static String getPrefVal(Context mContext, String key) { 
     SharedPreferences pref = getSharedPref(mContext); 
     String val = ""; 
     try { 
      if (pref.contains(key)) 
       val = pref.getString(key, ""); 
      else 
       val = ""; 
     }catch (Exception e){ 
      e.printStackTrace(); 
     } 
     return val; 
    } 

    public static int getIntPrefVal(Context mContext, String key) { 
     SharedPreferences pref = getSharedPref(mContext); 
     int val = 0; 
     try { 
     if(pref.contains(key)) val = pref.getInt(key, 0); 
     }catch (Exception e){ 
      e.printStackTrace(); 
     } 
     return val; 
    } 

    public static Long getLongPrefVal(Context mContext, String key) { 
     SharedPreferences pref = getSharedPref(mContext); 
     Long val = null; 
     try{ 
     if(pref.contains(key)) val = pref.getLong(key, 0); 
    }catch (Exception e){ 
     e.printStackTrace(); 
    } 
     return val; 
    } 

    public static boolean getBooleanPrefVal(Context mContext, String key) { 
     SharedPreferences pref = getSharedPref(mContext); 
     boolean val = false; 
     try{ 
     if(pref.contains(key)) val = pref.getBoolean(key, false); 

     }catch (Exception e){ 
      e.printStackTrace(); 
     } 
     return val; 
    } 


    public static boolean containkey(Context mContext,String key) 
    { 
     SharedPreferences pref = getSharedPref(mContext); 
     return pref.contains(key); 
    } 


} 
1
public class Prefs { 
private static final String KEY_TOKEN = "token"; 
private final SharedPreferences m_prefsRead; 
private final SharedPreferences.Editor m_prefsWrite; 

public Prefs(Context context) { 
    final String PREFS = "Sample"; 
    m_prefsRead = context.getSharedPreferences(PREFS, Context.MODE_PRIVATE); 
    m_prefsWrite = m_prefsRead.edit(); 
} 

public String getToken() { 
    return m_prefsRead.getString(KEY_TOKEN, null); 
} 

public void setToken(String accessToken) { 
    m_prefsWrite.putString(KEY_TOKEN, accessToken); 
    m_prefsWrite.commit(); 
} 

}

Initialise Prefs в файле приложения:

public class MyApp extends Application { 
private static MyApp m_instance; 
private Prefs m_prefs; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     m_instance = this; 

     m_prefs = new Prefs(this); 
    } 

    public static MyApp getInstance() { 
     return m_instance; 
    } 

    public Prefs getPrefs() { 
     return m_prefs; 
    } 
} 

Мы можем получить доступ к Prefs где-либо путем из приложения с помощью:. MyApp.getInstance() getPrefs() .getToken();

1

Посмотрите на это article. Все описано четко и учитываются лучшие практики. Код статьи:

public class PreferencesManager { 

    private static final String PREF_NAME = "com.example.app.PREF_NAME"; 
    private static final String KEY_VALUE = "com.example.app.KEY_VALUE"; 

    private static PreferencesManager sInstance; 
    private final SharedPreferences mPref; 

    private PreferencesManager(Context context) { 
     mPref = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); 
    } 

    public static synchronized void initializeInstance(Context context) { 
     if (sInstance == null) { 
      sInstance = new PreferencesManager(context); 
     } 
    } 

    public static synchronized PreferencesManager getInstance() { 
     if (sInstance == null) { 
      throw new IllegalStateException(PreferencesManager.class.getSimpleName() + 
        " is not initialized, call initializeInstance(..) method first."); 
     } 
     return sInstance; 
    } 

    public void setValue(long value) { 
     mPref.edit() 
       .putLong(KEY_VALUE, value) 
       .commit(); 
    } 

    public long getValue() { 
     return mPref.getLong(KEY_VALUE, 0); 
    } 

    public void remove(String key) { 
     mPref.edit() 
       .remove(key) 
       .commit(); 
    } 

    public boolean clear() { 
     return mPref.edit() 
       .clear() 
       .commit(); 
    } 
} 

Но вы можете изменить его в зависимости от ваших целей. На самом деле я не вижу ничего плохого, имея один синглтон, который будет обрабатывать все операции sharedprefs. Определенно, вы можете создать класс Util со статическими методами, использовать разные версии одноэлементного шаблона или даже напрямую использовать PreferencesManager (BTW это тоже синглтон). Лично я предпочитаю одноэлементный подход.

+0

Ответы не должны состоять в ссылке на статью, которая может закончиться нарушением в будущем. –

+0

Роджер, босс! –

0

Эй, я работал с настройками, и этот код кажется лучшим для меня! прост в обслуживании, вы можете настроить его и, например, добавить шифрование;).

в этом классе «MyPref» вы можете настраивать тип данных, хранящихся в ваших предпочтениях.

public class MyPref implements SharedPreferences { 
private SharedPreferences sharedPreferences; 


public MyPref(Context context, final String sharedPrefFilename) { 
    if (sharedPreferences == null) { 
     sharedPreferences = getSharedPreferenceFile(context, sharedPrefFilename); 
    } 
} 

private SharedPreferences getSharedPreferenceFile(Context context, String prefFilename) { 
    if (TextUtils.isEmpty(prefFilename)) { 
     return PreferenceManager 
       .getDefaultSharedPreferences(context); 
    } else { 
     return context.getSharedPreferences(prefFilename, Context.MODE_PRIVATE); 
    } 
} 

//----- SHARED PREFERENCES INTERFACE---- 
@Override 
public Map<String, ?> getAll() { 
    return sharedPreferences.getAll(); 
} 

@Override 
public String getString(String s, String s1) { 
    return sharedPreferences.getString(s,s1); 
} 

@Override 
public Set<String> getStringSet(String s, Set<String> set) { 
    return sharedPreferences.getStringSet(s,set); 
} 

@Override 
public int getInt(String s, int i) { 
    return sharedPreferences.getInt(s,i); 
} 

@Override 
public long getLong(String s, long l) { 
    return sharedPreferences.getLong(s,l); 
} 

@Override 
public float getFloat(String s, float v) { 
    return sharedPreferences.getFloat(s,v); 
} 

@Override 
public boolean getBoolean(String s, boolean b) { 
    return sharedPreferences.getBoolean(s,b); 
} 

@Override 
public boolean contains(String s) { 
    return sharedPreferences.contains(s); 
} 

@Override 
public Editor edit() { 
    return new MyEditor(); 
} 


@Override 
public void registerOnSharedPreferenceChangeListener(
     OnSharedPreferenceChangeListener listener) { 
    sharedPreferences.registerOnSharedPreferenceChangeListener(listener); 
} 

@Override 
public void unregisterOnSharedPreferenceChangeListener(
     OnSharedPreferenceChangeListener listener) { 
    sharedPreferences.unregisterOnSharedPreferenceChangeListener(listener); 
} 

/** 
* Inner class implements the Preference editor ,this class is responsible of preference editing (you can add encryption here). 
*/ 
    class MyEditor implements SharedPreferences.Editor { 

    private SharedPreferences.Editor mEditor; 

    private MyEditor() { 
     mEditor = sharedPreferences.edit(); 
    } 

    @Override 
    public Editor putString(String s, String s1) { 
     mEditor.putString(s,s1); 
     return this; 
    } 

    @Override 
    public Editor putStringSet(String s, Set<String> set) { 
     mEditor.putStringSet(s,set); 
     return this; 
    } 

    @Override 
    public Editor putInt(String s, int i) { 
     mEditor.putInt(s,i); 
     return this; 
    } 

    @Override 
    public Editor putLong(String s, long l) { 
     mEditor.putLong(s,l); 
     return this; 
    } 

    @Override 
    public Editor putFloat(String s, float v) { 
     mEditor.putFloat(s,v); 
     return this; 
    } 

    @Override 
    public Editor putBoolean(String s, boolean b) { 
     mEditor.putBoolean(s,b); 
     return this; 
    } 

    @Override 
    public Editor remove(String s) { 
     mEditor.remove(s); 
     return this; 
    } 

    @Override 
    public Editor clear() { 
     mEditor.clear(); 
     return this; 
    } 

    @Override 
    public boolean commit() { 
     return mEditor.commit(); 
    } 

    @Override 
    public void apply() { 
     mEditor.apply(); 
    } 
    } 
} 

в этом классе вы должны просто добавить ключ & Getter и Setter

public class Pref { 

private static final String MY_KEY1 = "MY_KEY1"; 
private static final String MY_KEY2 = "MY_KEY2"; 
private static final String MY_KEY3 = "MY_KEY3"; 

private static final String PREF_FILENAME = "MY_PREF_FILENAME"; 

private static SharedPreferences getSharedPreferences(Context context) { 
    return new MyPref(context , PREF_FILENAME); 
} 

private static SharedPreferences.Editor getEditor(Context context) { 
    return getSharedPreferences(context) 
      .edit(); 
} 

/* You have just to ADD you KEY & Getter and Setter*/ 
public static void putKey1(Context context, String date) { 
    getEditor(context).putString(MY_KEY1, date).apply(); 
} 

public static String getKey1(Context context) { 
    return getSharedPreferences(context).contains(MY_KEY1) ? 
      getSharedPreferences(context).getString(MY_KEY1, null) : 
      null; 
} 
public static void putKey2(Context context, String date) { 
    getEditor(context).putString(MY_KEY1, date).apply(); 
} 

public static String getKey2(Context context) { 
    return getSharedPreferences(context).contains(MY_KEY2) ? 
      getSharedPreferences(context).getString(MY_KEY2, null) : 
      null; 
} 
public static void putKey3(Context context, String date) { 
    getEditor(context).putString(MY_KEY1, date).apply(); 
} 

public static String getKey3(Context context) { 
    return getSharedPreferences(context).contains(MY_KEY3) ? 
      getSharedPreferences(context).getString(MY_KEY3, null) : 
      null; 
} 

} 

Использование:

public class MainActivity extends Activity { 
TextView hello; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    Pref.putKey1(this,"HELLO FROM PREFS"); 

    hello = (TextView) findViewById(R.id.hello); 
    hello.setText(Pref.getKey1(this)); 
} 
} 
Смежные вопросы