一、SharedPreferences将数据文件保存在指定路径上
通过反射:
private void initSharedPreferences(String path,String name,int mode) { try { Field field =ContextWrapper.class.getDeclaredField("mBase"); field.setAccessible(true); Object obj = field.get(this); field = obj.getClass().getDeclaredField("mPreferencesDir"); field.setAccessible(true); File file = new File(path); field.set(obj, file); sharedPreferences = getSharedPreferences(name, mode); editor = sharedPreferences.edit(); } catch (Exception e) { e.printStackTrace(); } }
原理:
查看getSharedPreferences源码(ContextImpl.java类)
@Override public SharedPreferences getSharedPreferences(String name, int mode) { SharedPreferencesImpl sp; synchronized (sSharedPrefs) { sp = sSharedPrefs.get(name); if (sp == null) { File prefsFile = getSharedPrefsFile(name); sp = new SharedPreferencesImpl(prefsFile, mode); sSharedPrefs.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; }
查看上段代码中红色方法getSharedPrefsFile(name):
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;
}
}
可以看到如果mPreferencesDir(一个全局变量,保存sharedPreferences的路径)为空时,就在默认路径下创建文件(data/data/packageName路径下),所以,先通过反射,将路径赋给mPreferencesDir变量,在调用getSharedPreferences-->getSharedPrefsFile-->getPreferencesDir时,返回的路径就是自定义的路径。此时就达到了修改存储路径的目的。