Android-SharedReferences-Context
我想使用kotlin在android中为我的Android-SharedReferences-Context,android,kotlin,sharedpreferences,android-context,Android,Kotlin,Sharedpreferences,Android Context,我想使用kotlin在android中为我的SharedReference创建一个助手类。 不幸的是,我需要上下文,我不想每次调用首选项时都将其设置为参数 如果我对上下文使用一个伴生对象,并在应用程序启动时设置它,我会得到以下错误:不要将Android上下文类放在静态字段中;这是内存泄漏(也会中断即时运行) 那么,如何在每次调用首选项时都不传递上下文呢 var isWorking: Boolean get() = getBoolean(IS_WORKING) set(isWor
SharedReference
创建一个助手类。
不幸的是,我需要上下文
,我不想每次调用首选项时都将其设置为参数
如果我对上下文使用一个伴生对象,并在应用程序启动时设置它,我会得到以下错误:不要将Android上下文类放在静态字段中;这是内存泄漏(也会中断即时运行)
那么,如何在每次调用首选项时都不传递上下文呢
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)
}
您可以创建一个
扩展函数
,如下所示:
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()
}
}
YourApp.prefHelper.defaultPrefs().edit {
// Your shared pref operations.
}
编辑:
是这个答案的参考。您可以使用Kotlin
技巧检查如何重构util类
,并使用它
Edit2:
您可以将助手更改为class,并在应用程序中初始化它。然后你可以在任何你想要的地方使用。我想这就是你想要做的。让我们做吧
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 YourApp : Application() {
override fun onCreate() {
super.onCreate()
YourApp.prefHelper = PreferenceHelper(this)
}
companion object {
lateinit var prefHelper: PreferenceHelper
private set
}
}
class SpInKotlinApp : Application() {
override fun onCreate() {
super.onCreate()
AppPreferences.init(this)
}
}
您可以在任何地方使用,如下所示:
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()
}
}
YourApp.prefHelper.defaultPrefs().edit {
// Your shared pref operations.
}
我认为第一个更接近最佳实践,但第二个也可以。你可以用你需要的。此外,我在上面提供的链接内容中还有更多很酷的例子。我找到了解决问题的方法。我通过持久化SharedReferences
变量而不是上下文来解决这个问题
object PreferenceDao {
private lateinit var settings: SharedPreferences
fun init(context: Context) {
settings = context.getSharedPreferences("prefs", Context.MODE_PRIVATE)
}
}
init函数在我的<代码>应用程序类.< /P> 中调用,而不是类,考虑使用对象。它只有一个实例,SharedReference可以用应用程序的上下文初始化,如下所示:
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 YourApp : Application() {
override fun onCreate() {
super.onCreate()
YourApp.prefHelper = PreferenceHelper(this)
}
companion object {
lateinit var prefHelper: PreferenceHelper
private set
}
}
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}")
}
检查完整的解释。这并不能回答您的问题,但您应该每次都通过上下文。正如消息所说,如果活动完成时操作仍在运行,则活动可能会泄漏。根据我的经验,我总是看到PreferenceHelper类在执行某些操作时接收上下文。请像我一样使用Kotlin扩展,谢谢您的回答。但这不是我真正想要的。我觉得用构造函数调用我的helper类没有什么区别。我编辑了我的答案,并尝试实现您想要做的事情。我更喜欢第一个,但第二个也是okeyMyApp.prefHelper.defaultPrefs().edit{}getting me错误,无法运行应用程序。您考虑过使用依赖项注入框架吗?这是什么?从未听说过。如果将参数更改为私有内联趣味SharedReferences.edit(操作:SharedReferences.Editor.(->Unit)
,则不需要在操作前面加它
。