티스토리 뷰
개요
기존 android 프로젝트에서 CMP 프로젝트로 변경하며 SharedPreferences를 DataStore로 마이그레이션하게 되었다.
기존 사용자들의 앱에 SharedPreferences로 저장된 기존 데이터들을 DataStore로 위임시킬 수 있다고 한다.
기존 데이터 옮기기
위임 패턴 사용하기(by)
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(
name = DATASTORE_FILE_NAME,
produceMigrations = { context ->
listOf(SharedPreferencesMigration(context, OLD_PREFS_FILE_NAME))
},
)
다음과 같이 기존에 SharedPreferences에 저장된 데이터가 있다면 DataStore를 생성하면서 SharedPreferences에 저장된 데이터를 복사하여 이동시켜준다.
이 프로퍼티의 선언은 싱글톤을 보장하기 위해 파일의 최상단이나 application 클래스에서 선언해야한다.
by preferences는 델리게이트(Delegate)방식이다. 이 방식은 PreferenceDataStoreSingletonDelegate 객체를 생성하며 위임을 통해 getValue를 호출하여 DataStore를 생성한다.
다음과 같은 특징이 있다.
- 싱글톤 보장: 이 방식으로 선언하면 앱전체에서 해당 이름의 DataStore 인스턴스가 단 하나만 존재하도록 라이브러리가 관리해준다.
- 중복 생성 방지: 만약 이 코드를 일반 class나 Activity 등에서 선언하고 사용할 경우 여러 개의 위임 객체가 생성된다. 이는 IllegalStateException이 발생하며 앱이 종료될 수 있다.
내부 구현
override fun getValue(thisRef: Context, property: KProperty<*>): DataStore<Preferences> {
return INSTANCE
?: synchronized(lock) {
if (INSTANCE == null) {
val applicationContext = thisRef.applicationContext
INSTANCE =
PreferenceDataStoreFactory.create(
corruptionHandler = corruptionHandler,
migrations = produceMigrations(applicationContext),
scope = scope,
) {
applicationContext.preferencesDataStoreFile(name)
}
}
INSTANCE!!
}
}
}
다음 코드는 PreferenceDataStoreSingletonDelegate 의 내부 함수이다. DataStore는 한개만 생성되도록 보장해주지만 PreferenceDataStoreSingletonDelegate 객체가 여러 번 생성될 수 있으므로 반드시 싱글톤으로 생성되도록 해야한다.
androidMain 코드
@BindingContainer
@ContributesTo(AppScope::class)
object DatabaseBindings {
@Provides
@SingleIn(AppScope::class)
fun provideDataStore(application: Application): DataStore<Preferences> =
PreferenceDataStoreFactory.create(
migrations = listOf(SharedPreferencesMigration(application, OLD_PREFS_FILE_NAME)),
produceFile = { application.preferencesDataStoreFile(DATASTORE_FILE_NAME) },
)
}
내 코드는 위임 방식을 사용하지 않고 PreferenceDataStoreFactory를 통해 직접 생성해주었다.
Metro DI를 사용하고 있기 때문에 @SingleIn 을 통해 싱글톤을 보장해주었다.
'CMP' 카테고리의 다른 글
| Ktorfit(Ktor + Retrofit) (0) | 2026.01.21 |
|---|