Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/216.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android-SharedReferences-Context_Android_Kotlin_Sharedpreferences_Android Context - Fatal编程技术网

Android-SharedReferences-Context

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

我想使用kotlin在android中为我的
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)
,则不需要在操作前面加