Как читать и записывать SharedPreferences при использовании "androidx.preference: preference-ktx: 1.1.1" с Kotlin? - PullRequest
0 голосов
/ 10 июля 2020

Обычно я использую Code A или Code B для чтения или записи SharedPreferences.

В настоящее время я обновляю свой проект, чтобы использовать "androidx.preference:preference-ktx:1.1.1" с Kotlin.

Есть ли лучший способ чтения и записи SharedPreferences, когда я использую "androidx.preference:preference-ktx:1.1.1" с Kotlin?

Код A

SharedPreferences prfs = getSharedPreferences("AUTHENTICATION_FILE_NAME", Context.MODE_PRIVATE);
String Astatus = prfs.getString("Authentication_Status", "");

Код B

SharedPreferences preferences = getSharedPreferences("AUTHENTICATION_FILE_NAME", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("Authentication_Id",userid.getText().toString());
editor.putString("Authentication_Password",password.getText().toString());
editor.putString("Authentication_Status","true");
editor.apply();

Ответы [ 4 ]

3 голосов
/ 16 июля 2020

Если вы не используете инструмент внедрения зависимостей, такой как hilt, koin, et c, лучше создать одноэлементный класс, который управляет значениями предпочтений, чтобы не получать SharedPreferences каждый раз, когда вы хотите прочитать или записать значение. SingletonHolder помогает вам создать одноэлементный класс с параметрами поточно-ориентированным способом.

В противном случае, если вы используете инструмент внедрения зависимостей в своем проекте, вы можете пропустить одноэлементный класс часть решения ниже, и пусть это сделает инструмент DI.

PrefManager.kt

import android.content.Context

class PrefManager private constructor(context: Context) {

    // ------- Preference Variables

    var authenticationId: String?
        get() = pref.getString("KEY_AUTHENTICATION_ID", null)
        set(value) = pref.edit { putString("KEY_AUTHENTICATION_ID", value) }

    var authenticationStatus: Boolean
        get() = pref.getBoolean("KEY_AUTHENTICATION_STATUS", false)
        set(value) = pref.edit { putBoolean("KEY_AUTHENTICATION_STATUS", value) }

    // ---------------------------------------------------------------------------------------------

    private val pref = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)

    fun clear() = pref.edit { clear() }

    companion object : SingletonHolder<PrefManager, Context>(::PrefManager) {
        private const val FILE_NAME = "AUTHENTICATION_FILE_NAME"
    }
}

SingletonHolder.kt

open class SingletonHolder<out T, in A>(private val constructor: (A) -> T) {

    @Volatile
    private var instance: T? = null

    fun getInstance(arg: A): T {
        return when {
            instance != null -> instance!!
            else -> synchronized(this) {
                if (instance == null) instance = constructor(arg)
                instance!!
            }
        }
    }
}

Использование:

Теперь мы можем читать значение, подобное следующему:

val authenticationId = PrefManager.getInstance(context).authenticationId

и для записи:

PrefManager.getInstance(context).authenticationId = "SOME VALUE"
0 голосов
/ 21 июля 2020

Если вы хотите сделать еще один шаг и повысить безопасность, вы можете использовать encrypted sharedPreferences параллельно, так как это только для Android M и выше. Это действительно просто, если вы используете DI:

interface SharedPrefs {
    var accessToken: String?
    fun get(): SharedPreferences
}

class SimplePreferences(context: Context) : SharedPrefs {
    private val preferences: SharedPreferences =
        context.getSharedPreferences("myapp_preferences", Context.MODE_PRIVATE)

    override fun get(): SharedPreferences = preferences

    override var accessToken: String?
        get() = preferences.getString(MyApp.ACCESS_TOKEN_PREF_KEY, null)
        set(value) = preferences.edit().putString(MyApp.ACCESS_TOKEN_PREF_KEY, value)
            .apply()
}

@TargetApi(Build.VERSION_CODES.M)
class EncryptedSharedPrefs(val context: Context) : SharedPrefs {

    private var encryptedPrefs: SharedPreferences = EncryptedSharedPreferences.create(
        context,
        "myapp_encrypted_prefs",
        MasterKey.Builder(context).build(),
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )

    override fun get(): SharedPreferences = encryptedPrefs

    override var accessToken: String?
        get() = encryptedPrefs.getString(MyApp.ACCESS_TOKEN_PREF_KEY, null)
        set(value) = encryptedPrefs.edit().putString(
            MyApp.ACCESS_TOKEN_PREF_KEY,
            value
        ).apply()
}

модуль koin:

single {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
         EncryptedSharedPrefs(applicationContext)
   } else
         SimplePreferences(applicationContext)
   }
}

Использование:

val sharedPrefs by inject<SharedPrefs>()

// read 
println(sharedPrefs.accessToken)

// write
sharedPrefs.accessToken = "qwerty"
0 голосов
/ 16 июля 2020

без написания собственного дополнительного кода, для вашего фрагмента кода B вы можете сделать это с помощью библиотеки ktx

val preferences = getSharedPreferences("AUTHENTICATION_FILE_NAME", MODE_PRIVATE)
preferences.edit {
   putString("Authentication_Id", userid.getText().toString())
   putString("Authentication_Password", password.getText().toString())
   putString("Authentication_Status", "true")
}
0 голосов
/ 10 июля 2020

В вашем файле Pref.class укажите Context конструктору.

    class Prefs constructor(
            private val context: Context
        ) {
    
       private fun getSharedPreferences(prefsName: String) =
            context.getSharedPreferences(prefsName, Context.MODE_PRIVATE)
    
        private val AUTH_PHONE = "auth_phone"
        private val KEY_AUTH_PHONE = "auth_phone"
        private val authPhone by lazy { getSharedPreferences(AUTH_PHONE) }
        
        var phoneNumber: String
            get() {
                return authPhone.getString(KEY_AUTH_PHONE, null) ?: return ""
            }
            set(value) {
                authPhone.edit()
                    .putString(KEY_AUTH_PHONE, value)
                    .apply()
            } 
}

Затем вы можете использовать его в своей деятельности.

  Pref(context).phoneNumber = "998998578086"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...