Normally, I use Code A or Code B to read or write SharedPreferences.
At present, I update my project to use "androidx.preference:preference-ktx:1.1.1"
with Kotlin.
Is there a better way to read and write SharedPreferences when I use "androidx.preference:preference-ktx:1.1.1"
with Kotlin ?
Code A
SharedPreferences prfs = getSharedPreferences("AUTHENTICATION_FILE_NAME", Context.MODE_PRIVATE);
String Astatus = prfs.getString("Authentication_Status", "");
Code 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();
If you're not using a dependency injection tool such as hilt
, koin
, etc, it's better to make a singleton class which manages preferences values to not to obtain a SharedPreferences
object each time you want to read or write a value. SingletonHolder
helps you make a singleton class with parameters in a thread-safe manner.
Otherwise, if you're using a dependency injection tool in your project, you can skip the singleton part of the below solution and let the DI tool do it.
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"
}
}
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!!
}
}
}
}
Now we can read a value like the following:
val authenticationId = PrefManager.getInstance(context).authenticationId
and in order to write:
PrefManager.getInstance(context).authenticationId = "SOME VALUE"