rot1024
8/12/2014 - 4:30 PM

SharedPreferenceのラッパークラス

SharedPreferenceのラッパークラス

package hoge;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.preference.PreferenceManager;

import hoge.R;

import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.Set;

public class Preference {

    private static Preference instance;

    public static Preference getInstance(Context context) {
        if (instance == null) instance = new Preference(context);
        return instance;
    }

    public static <E extends Enum<E>> E fromOrdinal(Class<E> enumClass, int ordinal) {
        E[] enumArray = enumClass.getEnumConstants();
        return enumArray[ordinal];
    }

    private class Pref<T> {
        String key;
        T value;
        T defValue;

        public Pref(String key, T defValue) {
            this.key = key;
            this.defValue = defValue;
        }
    }

    private Resources resources;
    private SharedPreferences sharedPreferences;
    private SharedPreferences.OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            updatePref(key);
        }
    };
    private HashMap<String, Pref<?>> prefMap = new HashMap<String, Pref<?>>();

    private Preference(Context context) {
        resources = context.getResources();
        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
        sharedPreferences.registerOnSharedPreferenceChangeListener(listener);

        // example
        initTimelineView();

        if (!isInitialized()) clear();
        else for (String key : prefMap.keySet()) {
            updatePref(key);
        }
    }

    public void clear() {
        final SharedPreferences.Editor e = sharedPreferences.edit().clear();
        for (String key : prefMap.keySet()) {
            final Pref pref = prefMap.get(key);
            if (pref == null || pref.defValue == null)
                throw new NullPointerException();

            pref.value = pref.defValue;

            if (pref.defValue instanceof Boolean) {
                e.putBoolean(key, (Boolean) pref.defValue);
            }
            else if (pref.defValue instanceof Integer) {
                e.putInt(key, (Integer) pref.defValue);
            }
            else if (pref.defValue instanceof Float) {
                e.putFloat(key, (Float) pref.defValue);
            }
            else if (pref.defValue instanceof Long) {
                e.putLong(key, (Long) pref.defValue);
            }
            else if (pref.defValue instanceof String) {
                e.putString(key, (String) pref.defValue);
            }
            else {
                try {
                    if (pref.defValue instanceof Set<?> &&
                            ((ParameterizedType) (pref.getClass().getDeclaredField("defValue").getGenericType())).getActualTypeArguments()[0].equals(String.class)) {
                        e.putStringSet(key, (Set<String>) pref.defValue);
                    } else {
                        throw new IllegalStateException("Type is unknown. ");
                    }
                } catch (Exception ignore) {
                    throw new IllegalStateException("Type is unknown. ");
                }
            }
        }
        e.commit();
        setInitialized();
    }

    private <T> void addPref(int keyResId, T defValue) {
        addPref(resources.getString(keyResId), defValue);
    }

    private <T> void addPref(String key, T defValue) {
        if (key == null || defValue == null)
            throw new NullPointerException();
        prefMap.put(key, new Pref<T>(key, defValue));
    }

    private void updatePref(String key) {
        final Pref pref = prefMap.get(key);
        final SharedPreferences.Editor e = sharedPreferences.edit();
        if (pref == null || pref.defValue == null)
            throw new NullPointerException();

        if (pref.defValue instanceof Boolean) {
            try {
                pref.value = sharedPreferences.getBoolean(key, (Boolean) pref.defValue);
                if (pref.value.equals(pref.defValue))
                    e.putBoolean(key, (Boolean) pref.defValue);
            } catch (ClassCastException ex) {
                pref.value = pref.defValue;
                e.putBoolean(key, (Boolean) pref.defValue);
            }
        }
        else if (pref.defValue instanceof Integer) {
            try {
                pref.value = sharedPreferences.getInt(key, (Integer) pref.defValue);
                if (pref.value.equals(pref.defValue))
                    e.putInt(key, (Integer) pref.defValue);
            } catch (ClassCastException ex) {
                pref.value = pref.defValue;
                e.putInt(key, (Integer) pref.defValue);
            }
        }
        else if (pref.defValue instanceof Float) {
            try {
                pref.value = sharedPreferences.getFloat(key, (Float) pref.defValue);
                if (pref.value.equals(pref.defValue))
                    e.putFloat(key, (Float) pref.defValue);
            } catch (ClassCastException ex) {
                pref.value = pref.defValue;
                e.putFloat(key, (Float) pref.defValue);
            }
        }
        else if (pref.defValue instanceof Long) {
            try {
                pref.value = sharedPreferences.getLong(key, (Long) pref.defValue);
                if (pref.value.equals(pref.defValue))
                    e.putLong(key, (Long) pref.defValue);
            } catch (ClassCastException ex) {
                pref.value = pref.defValue;
                e.putLong(key, (Long) pref.defValue);
            }
        }
        else if (pref.defValue instanceof String) {
            try {
                pref.value = sharedPreferences.getString(key, (String) pref.defValue);
                if (pref.value.equals(pref.defValue))
                    e.putString(key, (String) pref.defValue);
            } catch (ClassCastException ex) {
                pref.value = pref.defValue;
                e.putString(key, (String) pref.defValue);
            }
        }
        else {
            try {
                if (pref.defValue instanceof Set<?> &&
                        ((ParameterizedType) (pref.getClass().getDeclaredField("defValue").getGenericType())).getActualTypeArguments()[0].equals(String.class)) {
                    try {
                        pref.value = sharedPreferences.getStringSet(key, (Set<String>) pref.defValue);
                        if (pref.value.equals(pref.defValue))
                            e.putStringSet(key, (Set<String>) pref.defValue);
                    } catch (ClassCastException ex) {
                        pref.value = pref.defValue;
                        e.putStringSet(key, (Set<String>) pref.defValue);
                    }
                } else {
                    throw new IllegalStateException("Type is unknown. ");
                }
            } catch (Exception ignore) {
                throw new IllegalStateException("Type is unknown. ");
            }
        }

        e.commit();
    }

    private <T> T getValue(int keyResId) {
        return getValue(resources.getString(keyResId));
    }

    private <T> T getValue(String key) {
        try {
            return (T) prefMap.get(key).value;
        } catch (Exception e) {
            return null;
        }
    }

    private int getIntValue(String key) {
        try {
            return (Integer) prefMap.get(key).value;
        } catch (ClassCastException e) {
            return 0;
        }
    }

    private int getStringValueAsInt(int keyResId) {
        return getStringValueAsInt(resources.getString(keyResId));
    }

    private int getStringValueAsInt(String key) {
        final String v = getValue(key);
        if (v == null) return 0;
        try {
            return Integer.parseInt(v);
        } catch (NumberFormatException e) {
            return 0;
        }
    }

    // -----------------------------------------------------------------
    // ↓使い方の例

    // Timeline View
    private void initTimelineView() {
        addPref(R.string.pref_key_timeline_avatar_style, "0");
        addPref(R.string.pref_key_timeline_avatar_style_rt, "0");
        addPref(R.string.pref_key_timeline_avatar_quality, "1");
        addPref(R.string.pref_key_timeline_relative_time, true);
        addPref(R.string.pref_key_timeline_refresh_relative_time, true);
    }

    public enum AvatarStyle {
        ROUNDED, SQUARE, CIRCLE, NONE
    }
    public AvatarStyle getTimelineAvatarStyle() {
        return AvatarStyle.values()[getStringValueAsInt(R.string.pref_key_timeline_avatar_style)];
    }
    public AvatarStyle getTimelineRetweeterAvatarStyle() {
        switch (getStringValueAsInt(R.string.pref_key_timeline_avatar_style_rt)) {
            case 1:
                return AvatarStyle.ROUNDED;
            case 2:
                return AvatarStyle.SQUARE;
            case 3:
                return AvatarStyle.CIRCLE;
            case 4:
                return AvatarStyle.NONE;
            default:
                return getTimelineAvatarStyle();
        }
    }
    public enum AvatarQuality {
        ORIGINAL, HIGH, MEDIUM, LOW
    }
    public AvatarQuality getTimelineAvatarQuality() {
        return AvatarQuality.values()[getStringValueAsInt(R.string.pref_key_timeline_avatar_quality)];
    }
    public boolean isTimelineRelativeTimeEnable() {
        return getValue(R.string.pref_key_timeline_relative_time);
    }
    public boolean isTimelineRelativeTimeAutoRefreshEnable() {
        return getValue(R.string.pref_key_timeline_refresh_relative_time);
    }

}