转载自:https://blog.csdn.net/wxyyxc1992/article/details/17222841
他的博客是2013年的,我又去android27的源码里面找ContextImpl.java
连续按2次shift就能查找到了,记住是android-27androidapp的那个,不是rt.jarcomsuncorbaseimplcorba的那个
也可以sdk目录下查找
我的SDK目录C:UserslcyAppDataLocalAndroidSdksourcesandroid-27androidapp
SharedPreferences 不过是个接口,它定义了一些操作xml文件的方法,其真正实现类为SharedPreferencesImpl ,该类之前是ContextIml的内部类,但是现在单独出来了,仍然在sdk目录下。该类如下:
final class SharedPreferencesImpl implements SharedPreferences {
......
@Nullable
public String getString(String key, @Nullable String defValue) {/通过key值获取对应的value值
synchronized (mLock) {
awaitLoadedLocked();
String v = (String)mMap.get(key);
return v != null ? v : defValue;
}
}
@Nullable
public Set<String> getStringSet(String key, @Nullable Set<String> defValues) {
synchronized (mLock) {
awaitLoadedLocked();
Set<String> v = (Set<String>) mMap.get(key);
return v != null ? v : defValues;
}
}
......
public final class EditorImpl implements Editor {//获得该SharedPreferencesImpl对象对应的Edito类,对数据进行操作
private final Object mLock = new Object();
@GuardedBy("mLock")
private final Map<String, Object> mModified = Maps.newHashMap();
...
}
}
getSharedPreferences()方法本身是Context这个接口中定义的一个抽象方法,由ContextImpl类负责实现。调用getSharedPreferences()获取对应的的文件,该函数实现功能如下:
class ContextImpl extends Context {
......
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
// 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";
}
}
File file;
synchronized (ContextImpl.class) {
if (mSharedPrefsPaths == null) {
mSharedPrefsPaths = new ArrayMap<>();
}
file = mSharedPrefsPaths.get(name);
if (file == null) {
file = getSharedPreferencesPath(name);
mSharedPrefsPaths.put(name, file);
}
}
return getSharedPreferences(file, mode);
}
@Override
public SharedPreferences getSharedPreferences(File file, int mode) {
SharedPreferencesImpl sp;
synchronized (ContextImpl.class) {
final ArrayMap<File, SharedPreferencesImpl> cache = getSharedPreferencesCacheLocked();
sp = cache.get(file);
if (sp == null) {
checkMode(mode);
if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) {
if (isCredentialProtectedStorage()
&& !getSystemService(UserManager.class)
.isUserUnlockingOrUnlocked(UserHandle.myUserId())) {
throw new IllegalStateException("SharedPreferences in credential encrypted "
+ "storage are not available until after user is unlocked");
}
}
sp = new SharedPreferencesImpl(file, mode);
cache.put(file, sp);
return sp;
}
}
if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
getApplicationInfo().targetSdkVersion < 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;
}
......
}
========================================Talk is cheap, show me the code=======================================