|
package com.straucorp.datastorepreferences.delegates |
|
|
|
/** |
|
* @author Andre Straube - Created on 29/08/2021 |
|
*/ |
|
import android.content.Context |
|
import android.content.SharedPreferences |
|
import androidx.annotation.GuardedBy |
|
import kotlinx.coroutines.* |
|
import kotlin.properties.ReadOnlyProperty |
|
import kotlin.reflect.KProperty |
|
|
|
/** |
|
* Kotlin Delegate patra trabalhar com SharedPreferences |
|
* |
|
* Exemplo de uso: |
|
* |
|
* ``` |
|
* val Context.sharedPrefs by sharedPreferences(name = "app_settings") |
|
* |
|
* var appLaunchCount by IntPreference( |
|
* preferences = context.sharedPrefs, |
|
* key = "app_launch_count", |
|
* defaultValue = 0 |
|
* ) |
|
* ``` |
|
*/ |
|
@Suppress("MissingJvmstatic") |
|
fun sharedPreferences( |
|
name: String, |
|
scope: CoroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()) |
|
): ReadOnlyProperty<Context, SharedPreferences> { |
|
return SharedPreferencesDelegate(name, scope) |
|
} |
|
|
|
/** |
|
* Classe utilizada para facilitar o trabalho com SharedPreferences. |
|
*/ |
|
internal class SharedPreferencesDelegate internal constructor( |
|
private val name: String, |
|
private val scope: CoroutineScope |
|
) : ReadOnlyProperty<Context, SharedPreferences> { |
|
|
|
private val lock = Any() |
|
|
|
@GuardedBy("lock") |
|
@Volatile |
|
private var INSTANCE: SharedPreferences? = null |
|
|
|
/** |
|
* Obtem a instância do SharedPreferences. |
|
* Uma vez executado, não cria nova instancia da classe [SharedPreferences]. |
|
* [INSTANCE] Funciona como uma variavel Singleton. |
|
* [Context.getSharedPreferences] É executa em uma nova coroutine evitando |
|
* bloqueio de UI e erros de [StrictMode]. |
|
* |
|
* @param thisRef deve ser uma instancia de [Context] |
|
* @param property não utilizado |
|
*/ |
|
override fun getValue(thisRef: Context, property: KProperty<*>): SharedPreferences { |
|
return INSTANCE ?: synchronized(lock) { |
|
if (INSTANCE == null) { |
|
|
|
// Executa em uma nova coroutine |
|
INSTANCE = runBlocking(scope.coroutineContext) { |
|
withContext(scope.coroutineContext) { |
|
thisRef.applicationContext.getSharedPreferences(name, Context.MODE_PRIVATE) |
|
} |
|
} |
|
} |
|
INSTANCE!! |
|
} |
|
} |
|
} |