이번 포스팅에서는 SharedPreferences에 복잡한 형태의 데이터를 json 포맷으로 저장하고 불러오는 법에 대해 알아보도록 하겠습니다.
SharedPreferences 는 Key-Value 형태로 이루어진 딕셔너리를 저장하도록 설계된 저장장소인데요, 이 Value 부분에 json으로 구성된 긴 형태의 데이터를 저장함으로써 복잡한 형태의 데이터도 저장할 수가 있습니다.
이 때 앱 안의 데이터를 json으로 Serialize하고 다시 복원하는 Deserialize를 편하게 실행하게 해 주는 Gson 이라는 라이브러리가 있습니다. 이번 포스팅에서는 이 라이브러리를 활용하겠습니다.
여기서는 Data class 이해하고 RecyclerView에서 사용하기 강의에서 만들었던 프로젝트를 수정하면서 구현해보겠습니다.
라이브러리 추가
우선 Gson을 디펜던시에 추가합니다.
1
2
3
dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
}
화면 구성
다음은 로딩에 사용할 플로팅버튼을 화면에 추가해줍니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
<androidx.constraintlayout.widget.ConstraintLayout
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id= "@+id/button_load"
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:layout_marginEnd= "20dp"
android:layout_marginBottom= "20dp"
android:clickable= "true"
android:focusable= "true"
app:layout_constraintBottom_toBottomOf= "parent"
app:layout_constraintEnd_toEndOf= "parent"
app:srcCompat= "@android:drawable/ic_menu_add" />
</androidx.constraintlayout.widget.ConstraintLayout>
Key 준비
SharedPreferences에서는 데이터를 다룰때 키를 사용하므로 그때 사용할 키를 정의해줍니다. 평범하게 SharedPreferences를 이용하는 경우에는 각 밸류마다 서로다른 키를 지정해야하므로 많은 키를 지정해야 하는데 여기서는 모든 데이터를 뭉뚱그려서 하나의 키에 저장할 것이므로 데이터용 키는 하나만 만들면 됩니다.
1
2
3
4
companion object {
private const val KEY _PREFS = "shared_preferences"
private const val KEY _DATA = "monster_data"
}
savePref() 작성
다음은 데이터를 저장하는 함수를 만듭니다. 이미 SharedPreferences로 앱 설정값 저장하고 불러오기 강의에서 설명했던 방식과 유사한데요, gson을 사용하면 gson 인스턴스를 만들고, 그 인스턴스를 이용해서 데이터를 json으로 변환하는 작업이 추가됩니다. Recyclerview 어댑터 안의 데이터는 private를 떼어서 다른 클래스에서도 접근할수 있도록 합니다.
1
2
3
4
5
6
7
8
9
private fun savePref () {
val sharedPreferences = getSharedPreferences ( KEY_PREFS , Context . MODE_PRIVATE )
val editor = sharedPreferences . edit ()
val gson = Gson ()
val json = gson . toJson ( rvAdapter . dataSet )
editor . putString ( KEY_DATA , json )
editor . apply ()
Log . d ( "debug" , "Data saved" )
}
loadPref() 함수 작성
이번엔 데이터를 불러오는 함수를 만듭니다. 기존의 방법과 역시 동일한데, TypeToken 을 적용해서 데이터를 복원하는 부분이 추가되었습니다. json으로 SharedPreferences에 저장하는 순간 데이터가 가지고 있는 타입정보가 모두 사라지기 때문에 데이터를 복원하면서 타입정보를 다시 부여하기 위해 타입토큰을 사용합니다. 여기서는 <<ArrayList<Monster>>
라는 타입을 만들어서 데이터에 부여해 줍니다. 그리고 Recyclerview 어댑터 안의 데이터는 변경가능하도록 var
로 변경해줍니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private fun loadPref () {
val sharedPreferences = getSharedPreferences ( KEY_PREFS , Context . MODE_PRIVATE )
if ( sharedPreferences . contains ( KEY_DATA )) {
val gson = Gson ()
val json = sharedPreferences . getString ( KEY_DATA , "" )
try {
val typeToken = object : TypeToken < ArrayList < Monster >>() {}. type
rvAdapter . dataSet = gson . fromJson ( json , typeToken )
} catch ( e : JsonParseException ) {
e . printStackTrace ()
}
Log . d ( "debug" , "Data loaded" )
}
}
함수 실행
다음은 메인액티비티 안에서 savePref
와 loadPref
를 실행시키면 됩니다. loadPref
를 실행하고 어댑터에 데이터 변경을 알려주면 됩니다.
1
2
3
4
5
6
7
8
9
10
11
override fun onCreate ( savedInstanceState : Bundle ?) {
binding . buttonLoad . setOnClickListener {
loadPref ()
rvAdapter . notifyItemChanged ( 0 , rvAdapter . dataSet . size )
}
}
override fun onStop () {
super . onStop ()
savePref ()
}
이렇게 SharedPrefenrences와 Gson을 이용해서 복잡한 데이터를 json으로 저장하고 불러오는 법에 대해 알아보았습니다.
VIDEO