SharedPreference 工具类

来源:互联网 发布:手机淘宝联盟自己购买 编辑:程序博客网 时间:2024/05/01 19:57

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;
0 0