一、SharedPreferences将数据文件保存在指定路径上(修改SharedPreferences存储路径)
通过反射:
<span style="color:#333333;">private void initSharedPreferences(String path,String name,int mode) {
try {
</span><span style="color:#ff0000;">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);</span><span style="color:#333333;">
sharedPreferences = getSharedPreferences(name, mode);
editor = sharedPreferences.edit();
} catch (Exception e) {
e.printStackTrace();
}
}</span>
原理:
查看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时,返回的路径就是自定义的路径。此时就达到了修改存储路径的目的。
二、访问别的应用的SharedPreference
如:B要访问A中的SharedPreference
1、首先,A在创建SharedPreference时,需要指定权限Context.MODE_WORLD_READABLE或者Context.MODE_WORLD_WRITEABLE
getSharedPreferences("appPerferences", Context.MODE_WORLD_READABLE);
2、在B中首先要获得A的上下文对象 Context,然后通过A应用的Context来访问
Context appContext = createPackageContext("com.test.app", Context.CONTEXT_IGNORE_SECURITY);
SharedPreferences sharedPreferences = appContext.getSharedPreferences("appPerferences", Context.MODE_WORLD_READABLE);
String name = sharedPreferences.getString("name", "");
或者:
直接通过解析data/data/packageName(A应用包名)下面的sharedpreference文件