0

AndroidSharedPreferencesクラスの動作が嫌いです。私の主な理由は、アプリケーションの任意の部分でキーと値のペアを探すたびにデフォルト値を指定する必要があることです。ほとんどのアプリケーションがおそらく複数の場所でこれらの値を呼び出すという事実を考えると、このアプローチは、デフォルト設定を取得するための中心点がないため、予想されるアプリケーション/設定の動作で実際にエラーを促進し ます. 例: アクティビティ A getBoolean(key133, false)、アクティビティ B getBoolean(key133, true): 問題。

必要なアプリケーション設定値を に指定/保存することでこの問題を回避しました。また、指定された でデフォルト値を遅延検索HashMapするカスタムSharedPreferences派生クラスがありますHashMap。MyClass.getBoolean(key) または MyClass.getString(key) を呼び出すだけで、 のデフォルト値が検索され、HashMapまだ存在しない場合は返されて格納されます (.commit()-ing)。デフォルトの動作は を呼び出すことgetBoolean(key, default_value)です。アプリケーションの初期化時にすべての設定を保存することは、パフォーマンスに関してかなり悪いため、これはパフォーマンスにも有益です。

1 つの問題は解決しましたが、新しい問題があります。すべてのPreference派生クラスがデフォルト値を見つけることができません。これは、独自のSharedPreference派生方法を使用してデフォルトのアプリケーション設定を照会できないためです。これにより、アプリケーションは正常に動作しますが、設定ページを最初に開いたときにまだ(常に)保存されていないため、設定は実際にはデフォルト値を表示しません...

簡単に言うとPreference、これを防ぐためにクラスをオーバーライドするにはどうすればよいですか?

編集:問題を説明するコードと、この方法を選択した理由

private final static Context context                    = ApplicationSubclass.getApplicationContext_();
private final static SharedPreferences prefs            = PreferenceManager.getDefaultSharedPreferences(context);  
private final static SharedPreferences.Editor editor    = prefs.edit();
public static Map<String, Boolean> booleans             = new HashMap<String, Boolean>();
public static Map<String, Integer> longs                = new HashMap<String, Integer>();
public static Map<String, String> strings               = new HashMap<String, String>();
public static Map<String, Integer> integers             = new HashMap<String, Integer>();

public aPreferences(){
    initialise();
}//end constructor

public void initialise(){
    // setup default preferences
    setBooleans();
    //setLongs();
    setStrings();
    //setIntegers();
}//end method   

private void setBooleans(){
    booleans.put("does_this_work", true);
    booleans.put("is_it_easy", true);
    booleans.put("is_it_free_of_problems", false);
    // and some hundreds more
}//end method

private void setStrings(){
    strings.put("show_me", "Show me!");
    // and some hundreds more
}//end method

// work the magic here
public boolean getBoolean(String key){
    if (!prefs.contains(key)) putBoolean(key, booleans.get(key));
    return prefs.getBoolean(key, booleans.get(key));
}//end method

public void putBoolean(String key, boolean value){
    editor.putBoolean(key, value).commit();
}//end method

これは機能します:

private static aPreferences values = new aPreferences();
if (values.getBoolean("does_this_work")) // value initialised upon first access
    Log.d(getClass().getSimpleName(), values.getString("show_me"));

これはしません:

CheckBoxPreference sound = new CheckBoxPreference(this);
sound.setKey("does_this_work"); // value not initialised, so checkbox not checked
sound.setTitle(getResources().getString(R.string.sound_title));
sound.setSummary(getResources().getString(R.string.sound_text));
root.addPreference(sound);
4

1 に答える 1

0

このようなことを処理するために、独自のプリファレンス管理クラスを作成することをお勧めします。デフォルトが何であったかを知る必要がある場合は、独自のグローバルな get / set メソッドを設定し、デフォルト値を public static フィールドとして公開できます。このようなもの:

public class MyPreferences {

    private static final String INT_VALUE_1_KEY = "VALUE_1";
    public static final int INT_VALUE_1_DEFAULT = -1;

    public static void setDefaults(Context c) {
       SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
       Editor edit = prefs.edit();

       if (!prefs.contains(INT_VALUE_1_KEY)) {
          edit.putInt(INT_VALUE_1_KEY, INT_VALUE_1_DEFAULT);
       }
       // etc..

       edit.commit();
    }

    public static int getValue1(Context c) {
       SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c);
       return prefs.getInt(INT_VALUE_1_KEY, INT_VALUE_1_DEFAULT);
    }
}
于 2012-11-19T23:04:14.613 に答える