DataStore는 Android Jetpack의 일부로, SharedPreferences를 대체하기 위해 제공되는 새로운 데이터 저장 방식입니다. DataStore는 데이터의 일관성을 보장하고, 메인 스레드에서의 I/O 작업을 피할 수 있습니다. 이는 SharedPreferences에서 발생할 수 있는 ANR(Application Not Responding) 문제를 방지하고, 앱의 성능을 향상시킬 수 있습니다.
또한, DataStore는 Flow API를 통해 데이터를 제공합니다. 이를 통해 비동기적으로 데이터를 불러올 수 있으며, LiveData나 StateFlow와 같은 라이브러리를 사용하여 데이터의 변경을 감지하고 UI를 업데이트할 수 있습니다.
먼저, 의존성을 추가합니다.
gradle
implementation "androidx.datastore:datastore-preferences:1.0.0" // DataStore를 사용하기 위한 라이브러리
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" // LiveData를 사용하기 위한 라이브러리
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" // ViewModel을 사용하기 위한 라이브러리
그런 다음, DataStore를 설정하는 MyDataStore 클래스를 생성합니다.
DataStore를 사용할 때는 stringPreferencesKey라는 함수를 이용해 Preferences에 저장할 키를 생성합니다.
class MyDataStore(context : Context) {
private val Context.dataStore : DataStore<Preferences> by preferencesDataStore("user_pref") // "user_pref"라는 이름의 DataStore를 생성합니다.
private val mDataStore : DataStore<Preferences> = context.dataStore // DataStore를 초기화합니다.
private val USER_NAME_KEY = stringPreferencesKey("USER_NAME") // "USER_NAME"이라는 키를 생성합니다.
// 사용자 이름을 DataStore에 저장하는 메서드입니다.
suspend fun insertUserName(userName : String) {
mDataStore.edit { settings ->
settings[USER_NAME_KEY] = userName // "USER_NAME" 키에 사용자 이름을 저장합니다.
}
}
// "USER_NAME" 키에 저장된 사용자 이름을 불러오는 Flow입니다.
val getUserName : Flow<String> = mDataStore.data.map {
val userName = it[USER_NAME_KEY] ?: "default"
userName
}
}
MainViewModel에서는 MyDataStore를 통해 데이터를 처리합니다.
class MainViewModel(application: Application) : AndroidViewModel(application){
private val myDataStore = MyDataStore(application) // MyDataStore를 초기화합니다.
// 사용자 이름을 DataStore에 저장하는 메서드입니다.
fun insert(userName : String) = viewModelScope.launch {
myDataStore.insertUserName(userName)
}
// "USER_NAME" 키에 저장된 사용자 이름을 불러오는 LiveData입니다.
val read = myDataStore.getUserName.asLiveData()
}
마지막으로 MainActivity에서는 뷰 모델을 통해 데이터를 처리합니다.
class MainActivity : AppCompatActivity() {
private lateinit var viewModel : MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
val save1 = findViewById<Button>(R.id.save1)
save1.setOnClickListener {
val editText1 = findViewById<EditText>(R.id.editText1)
val insertText = editText1.text.toString()
viewModel.insert(insertText) // 저장 버튼을 누르면 사용자 이름을 저장합니다.
}
val read1 = findViewById<Button>(R.id.read1)
read1.setOnClickListener {
val readText1 = findViewById<TextView>(R.id.readText1)
viewModel.read.observe(this, Observer {
readText1.text = it.toString() // 읽기 버튼을 누르면 사용자 이름을 불러와 텍스트 뷰를 업데이트합니다.
})
}
}
}