不要滥用SharedPreference
这篇文章在使用SharedPreference上给出了很多好的建议。
- 不要存放大的key和value!我就不重复三遍了,会引起界面卡、频繁GC、占用内存等等,好自为之!
- 毫不相关的配置项就不要丢在一起了!文件越大读取越慢,不知不觉就被猪队友给坑了;蓝后,放进defalut的那个简直就是愚蠢行为!
- 读取频繁的key和不易变动的key尽量不要放在一起,影响速度。(如果整个文件很小,那么忽略吧,为了这点性能添加维护成本得不偿失)
- 不要乱edit和apply,尽量批量修改一次提交!
- 尽量不要存放JSON和HTML,这种场景请直接使用json!
- 不要指望用这货进行跨进程通信!!!
涉及源码
SharedPreferencesImpl.java(需翻墙)
ContextImpl.java(需翻墙)
获取SharePreferences对象的三种方式
要想使用SharedPreferences来存储数据,首先需要获取到SharedPreferences对象。Android 中主要提供了三种方法用于得到SharedPreferences对象。
Context.getSharedPreferences()
Context类中的getSharedPreferences()方法 此方法接收两个参数,第一个参数用于指定
SharedPreferences文件的名称,如果指定的文件不存在则会创建一个, SharedPreferences文件都是存放在/data/data/包名/shared_prefs/目录下的。第二个参数用于 指定操作模式,主要有两种模式可以选择,MODE_PRIVATE和 MODE_MULTI_PROCESS。MODE_PRIVATE仍然是默认的操作模式,和直接传入0效 果是相同的,表示只有当前的应用程序才可以对这个SharedPreferences文件进行读写。 MODE_MULTI_PROCESS则一般是用于会有多个进程中对同一个SharedPreferences文 件进行读写的情况。类似地,MODE_WORLD_READABLE和 MODE_WORLD_WRITEABLE这两种模式已在Android 4.2版本中被废弃。
Activity.getPreferences()
Activity类中的getPreferences()方法 这个方法和Context中的getSharedPreferences()方 法很相似,不过它只接收一个操作模式参数,因为使用这个方法时会自动将当前活动的 类名作为SharedPreferences的文件名。 最终还是调用了方法1中的方法,源码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33/**
* Retrieve a {@link SharedPreferences} object for accessing preferences
* that are private to this activity. This simply calls the underlying
* {@link #getSharedPreferences(String, int)} method by passing in this activity's
* class name as the preferences name.
*
* @param mode Operating mode. Use {@link #MODE_PRIVATE} for the default
* operation.
*
* @return Returns the single SharedPreferences instance that can be used
* to retrieve and modify the preference values.
*/
public SharedPreferences getPreferences(int mode) {
return getSharedPreferences(getLocalClassName(), mode);
}
/**
* Returns class name for this activity with the package prefix removed.
* This is the default name used to read and write settings.
*
* @return The local class name.
*/
public String getLocalClassName() {
final String pkg = getPackageName();
final String cls = mComponent.getClassName();
int packageLen = pkg.length();
if (!cls.startsWith(pkg) || cls.length() <= packageLen
|| cls.charAt(packageLen) != '.') {
return cls;
}
return cls.substring(packageLen+1);
}
PreferenceManager.getDefaultSharedPreferences()
PreferenceManager类中的getDefaultSharedPreferences()方法 这是一个静态方法,它 接收一个Context参数,并自动使用当前应用程序的包名作为前缀来命名 SharedPreferences文。最终还是调用了方法1中的方法,源码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/**
* Gets a SharedPreferences instance that points to the default file that is
* used by the preference framework in the given context.
*
* @param context The context of the preferences whose values are wanted.
* @return A SharedPreferences instance that can be used to retrieve and
* listen to values of the preferences.
*/
public static SharedPreferences getDefaultSharedPreferences(Context context) {
return context.getSharedPreferences(getDefaultSharedPreferencesName(context),
getDefaultSharedPreferencesMode());
}
/**
* Returns the name used for storing default shared preferences.
*
* @see #getDefaultSharedPreferences(Context)
* @see Context#getSharedPreferencesPath(String)
*/
public static String getDefaultSharedPreferencesName(Context context) {
return context.getPackageName() + "_preferences";
}
private static int getDefaultSharedPreferencesMode() {
return Context.MODE_PRIVATE;
}