Android - SharedPreferences - 上下文

Tho*_*mer 3 android android-context sharedpreferences kotlin

我想SharedPreference使用kotlin 为我的android 创建一个帮助器类.不幸的是我需要这个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)
}
Run Code Online (Sandbox Code Playgroud)

lom*_*mza 6

可以考虑使用对象而不是类。它只有一个实例,可以使用应用程序的上下文初始化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)
        }
}
Run Code Online (Sandbox Code Playgroud)

在应用程序类中:

class SpInKotlinApp : Application() {
    override fun onCreate() {
        super.onCreate()
        AppPreferences.init(this)
    }
}
Run Code Online (Sandbox Code Playgroud)

并且由于使用自定义get()和set()方法简化了对属性的读写,因此分配值非常容易:

if (!AppPreferences.firstRun) {
        AppPreferences.firstRun = true
        Log.d("SpinKotlin", "The value of our pref is: ${AppPreferences.firstRun}")
    }
Run Code Online (Sandbox Code Playgroud)

在这里查看整个说明。


sav*_*ion 5

您可以在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()
        }
}
Run Code Online (Sandbox Code Playgroud)

编辑: 以下是此答案的参考.您可以检查如何util classes使用Kotlin技巧重构并使用它.

EDIT2:

您可以将助手更改为课程并在您的课程中初始化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()
            }
    }
Run Code Online (Sandbox Code Playgroud)

在您的Application类中:

class YourApp : Application() {

    override fun onCreate() {
        super.onCreate()
        YourApp.prefHelper = PreferenceHelper(this)
    }

    companion object {
        lateinit var prefHelper: PreferenceHelper
            private set
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在下面的任何地方使用:

YourApp.prefHelper.defaultPrefs().edit {
    // Your shared pref operations.
}
Run Code Online (Sandbox Code Playgroud)

我认为第一个更接近最佳实践,但第二个也没关系.你可以使用你需要的那个.此外,我在上面提供的链接内容中有更多很酷的例子.