共享参数SharedPreferences是Android最简单的数据存储方式,常用于存取“Key-Value”键值对数据。在使用共享参数之前,要先调用getSharedPreferences方法声明文件名与操作模式,示例代码如下:
SharedPreferences sps = getSharedPreferences("share", Context.MODE_PRIVATE);
该方法的第一个参数是文件名,例子中的share表示当前的共享参数文件是share.xml;第二个参数是操作模式,一般填MODE_PRIVATE表示私有模式。
共享参数若要存储数据则需借助于Editor类,示例的Java代码如下:
SharedPreferences.Editor editor = sps.edit(); editor.putString("name", "阿四"); editor.putInt("age", 25); editor.putBoolean("married", false); editor.putFloat("weight", 50f); editor.commit();
使用共享参数读取数据则相对简单,直接调用其对象的get方法即可获取数据,注意get方法的第二个参数表示默认值,示例的Java代码如下:
String name = sps.getString("name", ""); int age = sps.getInt("age", 0); boolean married = sps.getBoolean("married", false); float weight = sps.getFloat("weight", 0);
从上述数据读写的代码可以看出,共享参数的存取操作有些繁琐,因此实际开发常将共享参数相关操作提取到一个工具类,在新的工具类中封装SharedPreferences的常用操作,下面便是一个共享参数工具类的Java代码例子:
public class SharedUtil { private static SharedUtil mUtil; private static SharedPreferences mShared; public static SharedUtil getIntance(Context ctx) { if (mUtil == null) { mUtil = new SharedUtil(); } mShared = ctx.getSharedPreferences("share", Context.MODE_PRIVATE); return mUtil; } public void writeShared(String key, String value) { SharedPreferences.Editor editor = mShared.edit(); editor.putString(key, value); editor.commit(); } public String readShared(String key, String defaultValue) { return mShared.getString(key, defaultValue); } }
有了共享参数工具类,外部读写SharedPreferences就比较方便了,比如下面的Java代码,无论是往共享参数写数据还是从共享参数读数据,均只要一行代码:
//调用工具类写入共享参数 SharedUtil.getIntance(this).writeShared("name", "阿四"); //调用工具类读取共享参数 String name = SharedUtil.getIntance(this).readShared("name", "");
不过这个工具类并不完善,因为它只支持字符串String类型的数据读写,并不支持整型、浮点数、布尔型等其它类型的数据读写。另外,如果外部需要先读取某个字段的数值,等处理完了再写回共享参数,则使用工具类也要两行代码(一行读数据、一行写数据),依旧有欠简洁。找毛病其实都是容易的,如果仍然使用Java编码,能完善的就完善,不能完善的也不必苛求了。
之所以挑Java实现方式的毛病,倒不是因为看它不顺眼整天吹毛求疵,而是因为Kotlin有更好的解决办法。为了趁热打铁方便比较两种方式的优劣,下面开门见山直接给出Kotlin封装共享参数的实现代码例子:
class Preference<T>(val context: Context, val name: String, val default: T) : ReadWriteProperty<Any?, T> { val prefs: SharedPreferences by lazy { context.getSharedPreferences("default", Context.MODE_PRIVATE) } override fun getValue(thisRef: Any?, property: KProperty<*>): T { return findPreference(name, default) } override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { putPreference(name, value) } private fun <T> findPreference(name: String, default: T): T = with(prefs) { val res: Any = when (default) { is Long -> getLong(name, default) is String -> getString(name, default) is Int -> getInt(name, default) is Boolean -> getBoolean(name, default) is Float -> getFloat(name, default) else -> throw IllegalArgumentException("This type can be saved into Preferences") } return res as T } private fun <T> putPreference(name: String, value: T) = with(prefs.edit()) { //putInt、putString等方法返回Editor对象 when (value) { is L