Android使用SharedPreferences getInt读取偏好整数时崩溃问题
问题根源
核心问题在于:ListPreference 默认会将选中的值以 String 类型存入 SharedPreferences,哪怕你配置的 entryValues 是数字数组。
当你调用 sharedPref.getInt() 读取时:
- 如果用户从未修改过该偏好,系统会使用你传入的默认值(
PrefDefValues.TestTime强转后的 Int),此时不会崩溃; - 一旦用户修改过偏好,SharedPreferences 里就会存储 String 类型的值,这时
getInt()尝试将 String 强转为 Integer,必然抛出ClassCastException。
你用 Any 存储默认值的写法本身没有问题,崩溃的本质是 ListPreference 的存储类型和读取方法不匹配。
解决方法
方法一:自定义 ListPreference 强制存储 Integer 类型
这是最彻底的解决方案,从根源上让偏好以 Int 类型存储,后续直接用 getInt() 读取即可:
class IntListPreference(context: Context, attrs: AttributeSet) : ListPreference(context, attrs) { override fun onSetInitialValue(restoreValue: Boolean, defaultValue: Any?) { super.onSetInitialValue(restoreValue, defaultValue?.toString()) } override fun setValue(value: String?) { super.setValue(value) // 将String值转成Int存入SharedPreferences value?.toIntOrNull()?.let { sharedPreferences.edit().putInt(key, it).apply() } } override fun getValue(): String? { // 读取时返回Int转成的String,保证和父类逻辑兼容 return sharedPreferences.getInt(key, defaultValue.toString().toInt()).toString() } }
然后在 preferences.xml 中替换原有的 ListPreference:
<your.package.name.IntListPreference android:key="pref_testtime" android:title="@string/pref_testtime" android:entries="@array/testtime_texts" android:entryValues="@array/testtime_values" android:defaultValue="@integer/pref_testtime_default" app:iconSpaceReserved="false" />
修改后,偏好会以 Int 类型存储,你原来的 sharedPref.getInt(TMSettings.TESTTIME.key, PrefDefValues.TestTime as Int) 代码可以正常运行。
方法二:封装工具方法简化 String 转 Int 操作
如果不想自定义 Preference,可封装工具方法统一处理读取逻辑,避免手动转换的繁琐:
fun SharedPreferences.getIntFromString(key: String, defaultValue: Int): Int { return getString(key, defaultValue.toString())?.toIntOrNull() ?: defaultValue }
调用时直接使用:
sharedPref.getIntFromString(TMSettings.TESTTIME.key, PrefDefValues.TestTime as Int)
内容的提问来源于stack exchange,提问作者Diego Perez
相关产品推荐
相关产品推荐

