안드로이드 애플리케이션에서 SharedPreferences를 사용하는 방법에는 여러 가지가 있다.
전역 변수 방식에서는 애플리케이션 전역에서 SharedPreferences 인스턴스를 접근할 수 있도록 설정한다.
// 애플리케이션의 전역에서 접근할 수 있는 MintPreference 객체를 선언
@HiltAndroidApp
class App : Application() {
companion object {
lateinit var mintPreference: MintPreference
private set
}
// 애플리케이션 초기화 시 MintPreference 인스턴스를 생성하고 초기화
override fun onCreate() {
super.onCreate()
mintPreference = MintPreference(applicationContext)
}
}
@HiltViewModel
class MintViewModel @Inject constructor() : ViewModel() {
init {
// App 클래스에서 생성된 mintPreference 인스턴스를 사용하여 id 값을 설정
App.mintPreference.id = "A"
}
}
장점:
단점:
추천:
DI 방식을 사용하면 의존성 주입을 통해 SharedPreferences 인스턴스를 관리한다.
@InstallIn(SingletonComponent::class)
@Module
class PreferenceModule {
// Application 인스턴스를 사용하여 MintPreference 인스턴스를 생성하고 반환
@Provides
@Singleton
fun provideMintPreference(application: Application): MintPreference {
return MintPreference(application)
}
}
@HiltViewModel
class MintViewModel @Inject constructor(
// MintPreference 인스턴스를 주입받음
private val mintPreference: MintPreference
) : ViewModel() {
init {
// ViewModel 초기화 시 MintPreference의 id 값을 설정
mintPreference.id = "A"
}
}
장점:
단점:
추천:
class APreference(context: Context) : BasePreference(context) {
var id by stringPref("")
}
class BPreference(context: Context) : BasePreference(context) {
var id by stringPref("")
}
@HiltViewModel
class MintViewModel @Inject constructor(
private val aPreference: APreference,
private val bPreference: BPreference
) : ViewModel() {
init {
aPreference.id = "A"
bPreference.id = "B"
// 예상과 다르게 BPreference의 id 값이 APreference에 반영됨
Log.d("APreference", aPreference.id) // 출력: "B"
}
}
문제의 원인은 stringPref 함수가 내부적으로 동일한 key 값을 사용하기 때문이다.
/**
* Delegate string shared preferences property.
* @param default default string value
* @param key custom preferences key
* @param commitByDefault commit this property instead of apply
*/
protected fun stringPref(
default: String = "",
key: String? = null,
commitByDefault: Boolean = commitAllPropertiesByDefault
): AbstractPref<String> = StringPref(default, key, commitByDefault)
해결법은 stringPref의 key 값을 유니크하게 설정해주는 것
class APreference(context: Context) : BasePreference(context) {
var id by stringPref("", key = "Aid")
}
class BPreference(context: Context) : BasePreference(context) {
var id by stringPref("", key = "Bid")
}