SharedPreference 工具类

SharedPreferenceUtil

import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.SharedPreferences;
import android.util.Base64;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.util.Map;

/**
 * Created by yangshuai on 2015/9/30 0030.
 */
public class SharedPreferenceUtil {

    private static SharedPreferences sharedPreferences;
    private static SharedPreferences.Editor editor;

    public static void init(Activity context) {
        if (sharedPreferences == null) {
            sharedPreferences = context.getPreferences(Context.MODE_PRIVATE);
        }

        if (editor == null) {
            editor = sharedPreferences.edit();
        }
    }

    public static void saveIntData(String key, int data){
        editor.putInt(key, data);
        editor.commit();
    }

    public static int getIntData(String key){
        return sharedPreferences.getInt(key, 0);
    }

    public static int getIntData(String key, int defaultValue){
        return sharedPreferences.getInt(key, defaultValue);
    }

    public static void saveStringData(String key, String data){
        editor.putString(key, data);
        editor.commit();
    }

    public static String getStringData(String key){
        return sharedPreferences.getString(key, "");
    }

    public static String getStringData(String key, String defaultValue){
        return sharedPreferences.getString(key, defaultValue);
    }

    public static void saveBooleanData(String key, boolean data){
        editor.putBoolean(key, data);
        editor.commit();
    }

    public static boolean getBooleanData(String key){
        return sharedPreferences.getBoolean(key, false);
    }

    public static boolean getBooleanData(String key, boolean defaultValue){
        return sharedPreferences.getBoolean(key, defaultValue);
    }

    public static void saveFloatData(String key, float data){
        editor.putFloat(key, data);
        editor.commit();
    }

    public static float getFloatData(String key){
        return sharedPreferences.getFloat(key, 0);
    }

    public static float getFloatData(String key, float defaultValue){
        return sharedPreferences.getFloat(key, defaultValue);
    }

    public static Map<String, ?> getAllData(){
       return sharedPreferences.getAll();
    }

 /* 存储一个序列化(实现 Serializable接口)的对象 */
    public static void saveSerializableObject(String key, Object object) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(object);
        saveStringData(key, Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT));
    }

    /* 获取序列化对象 */
    public static Object getSerializableObject(String key) throws IOException {
        byte[] base64Bytes = Base64.decode(getStringData(key).getBytes(), Base64.DEFAULT);
        ByteArrayInputStream bais = new ByteArrayInputStream(base64Bytes);
        ObjectInputStream ois = new ObjectInputStream(bais);
        try {
            return ois.readObject();
        } catch (ClassNotFoundException e) {
            return null;
        }
    }
}

使用文件流读取 SharedPreferences 数据文件

SharedPreferences 保存的数据文件存放在内部存储卡中,路径为:
/data/data/【包名】/shared_prefs.

 public static String useFileStreamReadSharedPreferencesData(Context context) {
        String content = "";
        String path = android.os.Environment.getDataDirectory().getAbsolutePath()
                + "/data/" + context.getPackageName() + "/shared_prefs/abc.xml";
        try {
            FileInputStream fileInputStream = new FileInputStream(path);
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            content = bufferedReader.readLine();
            fileInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return content;
    }

修改 SharedPreferences 的保存路径

代码

public void saveToSDcard(Context context) {
        try {
            /* 获取 ContextWrapper 对象中的 mBase 变量 */
            Field field = ContextWrapper.class.getDeclaredField("mBase");
            field.setAccessible(true);

            /* 获取mBase变量的值 */
            Object object = field.get(context);

            /* 获取 ContextImpl.mPreferencesDir 变量 */
            field = object.getClass().getDeclaredField("mPreferencesDir");
            field.setAccessible(true);

            /* 创建自定义路径 */
            File file = new File("/sdcard");

            /* 修改 mPreferencesDir 变量的值 */
            field.set(object, file);

            /* 执行该语句,在 /sdcard 目录中创建一个 save_data.xml 文件 */
            SharedPreferences sharedPreferences = context.getSharedPreferences("save_data", Activity.MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPreferences.edit();
            editor.putString("afra55", "AAA啊哈");
            editor.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

分析源码:

ContextWrapper.java

    @Override
    public SharedPreferences getSharedPreferences(String name, int mode) {
        return mBase.getSharedPreferences(name, mode);
    }

getSharedPreferences 调用 mBase.getSharedPreferences(name, mode) 返回SharedPreferences 对象。

public class ContextWrapper extends Context {
    Context mBase;
    ......
    }

跟踪 Context 类,找到了抽象方法:

public abstract SharedPreferences getSharedPreferences(String name,
            int mode);

在这里可以看到getSharedPreferences 方法肯定被某个类实现了,那么用mBase变量获取该类的名称。

        try {
            Field field = ContextWrapper.class.getDeclaredField("mBase");
            field.setAccessible(true);
            Object object = field.get(context);
            object.getClass().getName(); // 获取到名字
        } catch (Exception e) {
            e.printStackTrace();
        }

知道了实现抽象方法的类是 android.app.ContextImpl, 在ContextImpl 中找到了实现方法:

@Override
    public SharedPreferences getSharedPreferences(String name, int mode) {
        SharedPreferencesImpl sp;
        synchronized (ContextImpl.class) {
            if (sSharedPrefs == null) {
                sSharedPrefs = new ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>>();
            }

            final String packageName = getPackageName();
            ArrayMap<String, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName);
            if (packagePrefs == null) {
                packagePrefs = new ArrayMap<String, SharedPreferencesImpl>();
                sSharedPrefs.put(packageName, packagePrefs);
            }

            // At least one application in the world actually passes in a null
            // name.  This happened to work because when we generated the file name
            // we would stringify it to "null.xml".  Nice.
            if (mPackageInfo.getApplicationInfo().targetSdkVersion <
                    Build.VERSION_CODES.KITKAT) {
                if (name == null) {
                    name = "null";
                }
            }

            sp = packagePrefs.get(name);
            if (sp == null) {
                File prefsFile = getSharedPrefsFile(name); // 这里-----
                sp = new SharedPreferencesImpl(prefsFile, mode);
                packagePrefs.put(name, sp);
                return sp;
            }
        }
        if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
            getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
            // If somebody else (some other process) changed the prefs
            // file behind our back, we reload it.  This has been the
            // historical (if undocumented) behavior.
            sp.startReloadIfChangedUnexpectedly();
        }
        return sp;
    }
    @Override
    public File getSharedPrefsFile(String name) {
        return makeFilename(getPreferencesDir(), name + ".xml");
    }
    private File getPreferencesDir() {
        synchronized (mSync) {
            if (mPreferencesDir == null) {
                mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
            }
            return mPreferencesDir;
        }
    }

可以看到 ContextImpl 中有个变量 mPreferencesDir 保存存储路径,因此通过反射修改该变量即可。

private File mPreferencesDir;

以下为新的更好的一种形式

BaseSharePreference

public class BaseSharePreference {
    public static final String PREFERENCE = "base_" + AppCache.getContext().getResources().getString(R.string.app_name) + "_SharePreference";
    private static BaseSharePreference instance = null;

    private SharedPreferences mPreference;

    public static BaseSharePreference getInstance() {
        if (instance == null) {
            instance = new BaseSharePreference();
        }
        return instance;
    }

    public BaseSharePreference() {
        if (AppCache.getContext() != null) {
            try {
                mPreference = AppCache.getContext().getSharedPreferences(PREFERENCE, Context.MODE_PRIVATE);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public SharedPreferences getPreference() {
        return mPreference;
    }

    public void setValue(String key, Object value) {
        if (value == null) {
            return;
        }
        if (value instanceof String) {
            mPreference.edit().putString(key, (String) value).apply();
        } else if (value instanceof Boolean) {
            mPreference.edit().putBoolean(key, (Boolean) value).apply();
        } else if (value instanceof Integer) {
            mPreference.edit().putInt(key, (Integer) value).apply();
        } else if (value instanceof Long) {
            mPreference.edit().putLong(key, (Long) value).apply();
        } else if (value instanceof Float) {
            mPreference.edit().putFloat(key, (Float) value).apply();
        } else if (value instanceof Set) {
            //noinspection unchecked
            mPreference.edit().putStringSet(key, (Set<String>) value).apply();
        }
    }

    public boolean getBooleanValue(String key, boolean... value) {
        if (value != null && value.length > 0) {
            boolean result = value[0];
            return mPreference.getBoolean(key, result);
        }
        return mPreference.getBoolean(key, false);
    }

    public float getFloatValue(String key, Float... value) {
        if (value != null && value.length > 0) {
            float result = value[0];
            return mPreference.getFloat(key, result);
        }
        return mPreference.getFloat(key, 0f);
    }

    public int getIntValue(String key, int... value) {
        if (value != null && value.length > 0) {
            int result = value[0];
            return mPreference.getInt(key, result);
        }
        return mPreference.getInt(key, 0);
    }

    public long getLongValue(String key, Long... value) {
        if (value != null && value.length > 0) {
            long result = value[0];
            return mPreference.getLong(key, result);
        }
        return mPreference.getLong(key, 0l);
    }

    public String getStringValue(String key, String... value) {
        if (value != null && value.length > 0) {
            String result = value[0];
            return mPreference.getString(key, result);
        }
        return mPreference.getString(key, "");
    }

    public Set<String> getSetValue(String key) {
        return mPreference.getStringSet(key, null);
    }



    public void setBaseBean(BaseBean update) {
        try {
            String info = JSONObject.toJSONString(update);
            setValue("base_bean", info);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setObject(String key, Object obj) {
        String info = JSONObject.toJSONString(obj);
        setValue(key, info);
    }

    public Object getObject(String key, Class cls) {
        if (!getStringValue(key, "").equals("")) {
            return JSONObject.parseObject(getStringValue(key, ""), cls);
        }
        return null;
    }

    public BaseBean getBaseBean() {
        try {
            if (!getStringValue("base_bean", "").equals("")) {
                BaseBean info = JSONObject.parseObject(getStringValue("appUpdateinfo", ""), BaseBean.class);
                return info;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public void clearAll() {
        try {
            mPreference.edit().clear().apply();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}

AppSharePreference


public class AppSharePreference extends BaseSharePreference {

    private static String SHARED_KEY_SETTING_GROUPS_SYNCED = "SHARED_KEY_SETTING_GROUPS_SYNCED";
    private static String SHARED_KEY_SETTING_CONTACT_SYNCED = "SHARED_KEY_SETTING_CONTACT_SYNCED";
    private static String SHARED_KEY_SETTING_BALCKLIST_SYNCED = "SHARED_KEY_SETTING_BALCKLIST_SYNCED";


    private static AppSharePreference instance = null;

    public static AppSharePreference getInstance() {
        if (instance == null) {
            synchronized (AppSharePreference.class) {
                instance = new AppSharePreference();
            }
        }
        return instance;
    }

    private AppSharePreference() {
        super();
    }

    public void setIsChina(boolean isChina) {
        setValue("isChina", isChina);
    }

    public boolean isChina() {
        return getBooleanValue("isChina", false);
    }

    public void setBlacklistSynced(boolean synced) {
        setValue(SHARED_KEY_SETTING_BALCKLIST_SYNCED, synced);

    }

    public boolean isBacklistSynced() {
        return getBooleanValue(SHARED_KEY_SETTING_BALCKLIST_SYNCED, false);
    }

    public void setGroupsSynced(boolean synced) {
        setValue(SHARED_KEY_SETTING_GROUPS_SYNCED, synced);
    }

    public boolean isGroupsSynced() {
        return getBooleanValue(SHARED_KEY_SETTING_GROUPS_SYNCED, false);
    }

    public void setContactSynced(boolean synced) {
        setValue(SHARED_KEY_SETTING_CONTACT_SYNCED, synced);
    }

    public boolean isContactSynced() {
        return getBooleanValue(SHARED_KEY_SETTING_CONTACT_SYNCED, false);
    }

    public boolean isAPKAlreadyOpen(String path) {
        return getBooleanValue("APK_ALREADY_OPED" + path, false);
    }

    public void setAPKAlreadyOpen(String path, boolean value) {
        setValue("APK_ALREADY_OPED" + path, value);
    }

    public void saveLastGetVCodeTime(long mills) {
        setValue("LAST_VCODE_GET", mills);
    }

    public long getLastGetVCodeTime() {
        return getLongValue("LAST_VCODE_GET", 0L);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值