SharedPreferences 源码及原理
SharedPreferences 是Android中提供的一种轻量级数据存储方式,用来以键值对方式保存简单的数据类型。
创建流程
Android开发者通过Context的方法context.getSharedPreferences(String, Int)
来获取SharedPreferences实例。Context中的具体实现如下
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
return mBase.getSharedPreferences(name, mode);
}
其直接调用了Context
中代理模式的mBase
的实现。mBase
是一个ContextImpl
实例。其内部方法实现如下
// 通过名称获取SharedPreferences实例
@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 File getSharedPreferencesPath(String name) {
return makeFilename(getPreferencesDir(), name + ".xml");
}
// 获取文件夹路径
private File getPreferencesDir() {
synchronized (mSync) {
if (mPreferencesDir == null) {
mPreferencesDir = new File(getDataDir(), "shared_prefs");
}
return ensurePrivateDirExists(mPreferencesDir);
}
}
ContextImpl
通过 mSharedPrefsPaths
缓存文件实例,它是一个ArrayMap<String, File>
格式的变量。若缓存中没有目标文件,则通过getSharedPreferencesPath()
方法生成,并将其放入缓存。然后通过getSharedPreferences(File, Int)
方法真正创建实例。通过源码可知,其路径在应用的getDataDir()
路径下的"shared_prefs" 文件夹内,以"${name}.xml"命名。
// 通过文件获取SharedPreferences实例
@Override
public SharedPreferences getSharedPreferences(File file, int mode) {
checkMode(mode);
if (getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.O) {
if (isCredentialProtectedStorage