Android - 共享首选项 - 上下文
Android - SharedPreferences - Context
我想使用 kotlin 为 android 中的 SharedPreference
创建一个助手 class。
不幸的是,我需要 Context
,但我不想每次调用首选项时都将其设置为参数。
如果我为上下文使用伴随对象并在应用程序启动时设置它,我会收到以下错误:Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)
那么如何在每次调用首选项时获取上下文而不传递它?
var isWorking: Boolean
get() = getBoolean(IS_WORKING)
set(isWorking) = setPreference(IS_WORKING, isWorking)
private fun setPreference(key: String, value: Boolean) {
val editor = settings.edit()
editor.putBoolean(key, value)
editor.commit()
}
private val settings: SharedPreferences by lazy {
context.getSharedPreferences("prefs", Context.MODE_PRIVATE)
}
您可以像下面这样创建 extension function
:
object PreferenceHelper {
fun defaultPrefs(context: Context): SharedPreferences
= PreferenceManager.getDefaultSharedPreferences(context)
fun customPrefs(context: Context, name: String): SharedPreferences
= context.getSharedPreferences(name, Context.MODE_PRIVATE)
inline fun SharedPreferences.edit(operation: (SharedPreferences.Editor) -> Unit) {
val editor = this.edit()
operation(editor)
editor.apply()
}
}
编辑:
Here 是这个答案的参考。您可以检查如何使用 Kotlin
技巧重构 util classes
并使用它。
编辑2:
您可以将您的助手更改为 class 并在您的 Application
中初始化它。然后你可以在任何你想用的地方使用。我认为这就是你想要做的。让我们开始吧。
class PreferenceHelper constructor(context: Context){
fun defaultPrefs(): SharedPreferences
= PreferenceManager.getDefaultSharedPreferences(context)
fun customPrefs(name: String): SharedPreferences
= context.getSharedPreferences(name, Context.MODE_PRIVATE)
inline fun SharedPreferences.edit(operation: (SharedPreferences.Editor) -> Unit) {
val editor = this.edit()
operation(editor)
editor.apply()
}
}
在你的申请中class:
class YourApp : Application() {
override fun onCreate() {
super.onCreate()
YourApp.prefHelper = PreferenceHelper(this)
}
companion object {
lateinit var prefHelper: PreferenceHelper
private set
}
}
您可以像下面这样在任何地方使用:
YourApp.prefHelper.defaultPrefs().edit {
// Your shared pref operations.
}
我认为第一个更接近最佳实践,但第二个也不错。你可以使用你需要的那个。此外,我在上面提供的 link 内容中还有更多很酷的示例。
我找到了解决问题的方法。我通过保留 SharedPreferences
变量而不是上下文来解决它。
object PreferenceDao {
private lateinit var settings: SharedPreferences
fun init(context: Context) {
settings = context.getSharedPreferences("prefs", Context.MODE_PRIVATE)
}
}
在我的 Application
class 中调用了 init 函数。
考虑使用对象而不是 class。它只有一个实例,并且 SharedPreferences 可以使用应用程序的上下文进行初始化,如下所示:
object AppPreferences {
private const val NAME = "SpinKotlin"
private const val MODE = Context.MODE_PRIVATE
private lateinit var preferences: SharedPreferences
// list of app specific preferences
private val IS_FIRST_RUN_PREF = Pair("is_first_run", false)
fun init(context: Context) {
preferences = context.getSharedPreferences(NAME, MODE)
}
/**
* SharedPreferences extension function, so we won't need to call edit()
and apply()
* ourselves on every SharedPreferences operation.
*/
private inline fun SharedPreferences.edit(operation:
(SharedPreferences.Editor) -> Unit) {
val editor = edit()
operation(editor)
editor.apply()
}
var firstRun: Boolean
// custom getter to get a preference of a desired type, with a predefined default value
get() = preferences.getBoolean(IS_FIRST_RUN_PREF.first, IS_FIRST_RUN_PREF.second)
// custom setter to save a preference back to preferences file
set(value) = preferences.edit {
it.putBoolean(IS_FIRST_RUN_PREF.first, value)
}
}
申请中class:
class SpInKotlinApp : Application() {
override fun onCreate() {
super.onCreate()
AppPreferences.init(this)
}
}
并且由于使用自定义 get() 和 set() 方法简化了对属性的读写,因此赋值非常容易:
if (!AppPreferences.firstRun) {
AppPreferences.firstRun = true
Log.d("SpinKotlin", "The value of our pref is: ${AppPreferences.firstRun}")
}
查看完整解释here。
我想使用 kotlin 为 android 中的 SharedPreference
创建一个助手 class。
不幸的是,我需要 Context
,但我不想每次调用首选项时都将其设置为参数。
如果我为上下文使用伴随对象并在应用程序启动时设置它,我会收到以下错误:Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)
那么如何在每次调用首选项时获取上下文而不传递它?
var isWorking: Boolean
get() = getBoolean(IS_WORKING)
set(isWorking) = setPreference(IS_WORKING, isWorking)
private fun setPreference(key: String, value: Boolean) {
val editor = settings.edit()
editor.putBoolean(key, value)
editor.commit()
}
private val settings: SharedPreferences by lazy {
context.getSharedPreferences("prefs", Context.MODE_PRIVATE)
}
您可以像下面这样创建 extension function
:
object PreferenceHelper {
fun defaultPrefs(context: Context): SharedPreferences
= PreferenceManager.getDefaultSharedPreferences(context)
fun customPrefs(context: Context, name: String): SharedPreferences
= context.getSharedPreferences(name, Context.MODE_PRIVATE)
inline fun SharedPreferences.edit(operation: (SharedPreferences.Editor) -> Unit) {
val editor = this.edit()
operation(editor)
editor.apply()
}
}
编辑:
Here 是这个答案的参考。您可以检查如何使用 Kotlin
技巧重构 util classes
并使用它。
编辑2:
您可以将您的助手更改为 class 并在您的 Application
中初始化它。然后你可以在任何你想用的地方使用。我认为这就是你想要做的。让我们开始吧。
class PreferenceHelper constructor(context: Context){
fun defaultPrefs(): SharedPreferences
= PreferenceManager.getDefaultSharedPreferences(context)
fun customPrefs(name: String): SharedPreferences
= context.getSharedPreferences(name, Context.MODE_PRIVATE)
inline fun SharedPreferences.edit(operation: (SharedPreferences.Editor) -> Unit) {
val editor = this.edit()
operation(editor)
editor.apply()
}
}
在你的申请中class:
class YourApp : Application() {
override fun onCreate() {
super.onCreate()
YourApp.prefHelper = PreferenceHelper(this)
}
companion object {
lateinit var prefHelper: PreferenceHelper
private set
}
}
您可以像下面这样在任何地方使用:
YourApp.prefHelper.defaultPrefs().edit {
// Your shared pref operations.
}
我认为第一个更接近最佳实践,但第二个也不错。你可以使用你需要的那个。此外,我在上面提供的 link 内容中还有更多很酷的示例。
我找到了解决问题的方法。我通过保留 SharedPreferences
变量而不是上下文来解决它。
object PreferenceDao {
private lateinit var settings: SharedPreferences
fun init(context: Context) {
settings = context.getSharedPreferences("prefs", Context.MODE_PRIVATE)
}
}
在我的 Application
class 中调用了 init 函数。
考虑使用对象而不是 class。它只有一个实例,并且 SharedPreferences 可以使用应用程序的上下文进行初始化,如下所示:
object AppPreferences {
private const val NAME = "SpinKotlin"
private const val MODE = Context.MODE_PRIVATE
private lateinit var preferences: SharedPreferences
// list of app specific preferences
private val IS_FIRST_RUN_PREF = Pair("is_first_run", false)
fun init(context: Context) {
preferences = context.getSharedPreferences(NAME, MODE)
}
/**
* SharedPreferences extension function, so we won't need to call edit()
and apply()
* ourselves on every SharedPreferences operation.
*/
private inline fun SharedPreferences.edit(operation:
(SharedPreferences.Editor) -> Unit) {
val editor = edit()
operation(editor)
editor.apply()
}
var firstRun: Boolean
// custom getter to get a preference of a desired type, with a predefined default value
get() = preferences.getBoolean(IS_FIRST_RUN_PREF.first, IS_FIRST_RUN_PREF.second)
// custom setter to save a preference back to preferences file
set(value) = preferences.edit {
it.putBoolean(IS_FIRST_RUN_PREF.first, value)
}
}
申请中class:
class SpInKotlinApp : Application() {
override fun onCreate() {
super.onCreate()
AppPreferences.init(this)
}
}
并且由于使用自定义 get() 和 set() 方法简化了对属性的读写,因此赋值非常容易:
if (!AppPreferences.firstRun) {
AppPreferences.firstRun = true
Log.d("SpinKotlin", "The value of our pref is: ${AppPreferences.firstRun}")
}
查看完整解释here。