Tech Log

[Android] SharedPreferences 본문

Android/etc

[Android] SharedPreferences

yuhee kim 2022. 6. 15. 21:26

로그인 기능이 있는 어플리케이션을 만들 때, SharedPrefereces를 사용한 적이 있다. SharedPreferences는 DB를 라이트하게 쓰고 싶을 때 그리고 앱이 종료돼도 데이터를 저장하고 싶을 때? 사용하는 것으로 알고 있다.

SharedPreferences에 대한 개념에 확신이 없어서 블로그에 글을 쓰면서 공부해본다.

 

 

1. SharedPreferences란?

SharedPreferences는 데이터를 저장하는 안드로이드 API다.

우리는 보통 데이터를 저장할 때 DataBase를 사용한다.

SQLite를 쓰거나 MySQL과 같은 DataBase에 많은 데이터를 보관한다.

 

이러한 DB들이 있는데도 SharedPreferences를 쓰는 것은, 간단한 저장을 하기 위해서이다.

간단한 설정 값들이나 여러 데이터들의 수가 DataBase에 저장할 만큼 많지 않고 비교적 적다면 SharedPreferences를 쓰는 것이 더 간편하다.

데이터 로드(load) 속도가 DataBase보다 빠르고 복잡한 절차없이 간편하게 저장할 수 있기 때문이다.

 

Preference API  랑 다른 것이다.

 

 

2. 특징

  • xml 파일 형태로 데이터를 저장 (data/data/패키지명/shared_prefs/SharedPreferences
    • 파일 형태로 저장되므로 너무 많은 데이터를 넣게 되면 메모리 예외가 나타날 수 있다
    • 파일 형태로 저장되므로 메모리 손상의 위험에 영향이 갈 수 있다
    • 보안에 취약하므로 보안이 요구되는 데이터들은 SharedPreferences로 저장하지 않는 것이 좋다
  • 어플리케이션이 삭제되기 전까지 데이터가 보존된다
  • Key-Value 형태로 데이터가 저장된다
  • 불러오려는 Key 값이 없는 경우 공백 문자열을 return 한다
  • 초기 설정값(자동 로그인 여부, 진동 유무 등)과 같이 간단한 값을 저장하고 싶을 때 사용

 

3. 사용하기

 

SharedPreferences handle(인스턴스) 가져오기

- getSharedPreferences() : 여러 Activity에서 사용하는 SharedPreferences를 생성, 주로 어플리케이션 전체에서 사용

해당 메소드를 사용하면, SharedPreferences 파일이 여러 개 생성될 수 있다. 첫 번째 Paremeter에 SharedPreferences 파일의 이름이 들어간다. 앱의 모든 Context에서 이 메소드를 호출할 수 있다.

아래와 같이 사용된다.

 

Context.getSharedPreferences(String, Int) 

첫 번째 Parameter에 파일 이름을 지정해준다.

두 번째 Parameter에는 파일 읽기 관련 MODE를 설정해준다.

 

코드 예시

val spf : SharedPreferences = context.getSharedPreferences("file_name", Context.MODE_PRIVATE)

 

저장 MODE에는 아래와 같은 것들이 있다.

MODE 의미
MODE_PRIVATE 어플리케이션 내에서 사용 가능, 외부 어플리케이션에서는 사용 불가, default 값
MODE_WORLD_READABLE 외부 어플리케이션에서 읽기 가능 (API 17부터 deprecated)
MODE_WORLD_WRITEABLE 외부 어플리케이션에서 쓰기 가능 (API 17부터 deprecated)

보안 문제로 인해 MODE_WORLD_READABLE과 MODE_WORLD_WRITEABLE이 API 17부터 deprecated되었다고 한다.

 

- getPreferences() : 하나의 Activity에서만 사용하는 SharedPreferences를 생성. 하나의 Activity에서만 사용하므로 Parameter에서 이름을 지을 필요 없다.

따라서 getPreferences에는 어떤 MODE로 저장할 것인지의 값만 Parameter로 넘기면 된다.

아래와 같이 사용

 

Context.getPreferences(Int)

Int에는 파일 읽기 관련 Parameter가 들어간다.

 

코드 예시

val spf : SharedPreferences = context.getPreferences(MODE_PRIVATE)

 

 

SharedPreferences에 데이터 쓰기

SharedPreferences 클래스의 edit Interface를 호출하여 저장할 데이터를 xml 파일에 작성한다.

 

코드 예시

val spf : SharedPreferences = context.getPreferences(Context.MODE_PRIVATE)
val editor = spf.edit()

 

Intent에서 값을 전달해주듯이, putInt() 혹은 putString() 메소드를 사용하여

 

데이터를 쓸 수 있는 메소드의 종류는 아래와 같다.

 

  • putBoolean()
  • putFloat()
  • putInt()
  • putLong()
  • putString()
  • putStringSet()

 

SharedPreferences 파일에 쓰려고 하는 Key(데이터 이름)와 Value(데이터)를 전달한다.

그 다음에 apply() 또는 commit()을 호출하면 SharedPreferences 파일에 데이터가 쓰인다.

 

코드 예시

val spf : SharedPreferences = context.getPreferences(Context.MODE_PRIVATE)
val editor = spf.edit()
editor.putInt("count", 1).apply()

 

commit()과 apply()의 차이

- apply() : 메모리 내의 SharedPreferences 객체를 즉시 변경하지만 디스크에 비동기적으로 업데이트한다. 즉, 호출 후 바로 return 되어 스레드를 block 시키지 않는다.

- commit() : 호출 시 스레드는 block되며, 디스크에 값을 동기적으로 업데이트한다. ANR을 막기 위해 메인 스레드에서 호출하는 것을 주의해야 한다. 처리 결과를 True/False로 반환한다. 결과값이 필요없는 경우 apply()를 사용하는 것이 반응성면에서 좋을 수 있다.

 

 

SharedPreferences에 데이터 읽기

getInt() 혹은 getString() 메소드를 호출하여 불러오고 싶은 데이터의 Key 값을 Parameter에 넣어 데이터를 가져온다.

해당 메소드의 두 번째 Parameter에는 SharedPreferences 파일에 Key 값에 해당하는 값이 없을 시에 반환할 값을 적어준다.

 

데이터를 읽을 수 있는 Type의 종류는 아래와 같다.

 

  • getAll() //SharedPreferences 파일 내의 모든 데이터를 가져온다. return되는 값은 Map<String, ?> 형태이다.
  • getBoolean()
  • getFloat()
  • getInt()
  • getLong()
  • getString()
  • getStringSet()

 

 

코드 예시

val spf : SharedPreferences = context.getPreferences(Context.MODE_PRIVATE)
val userCount = spf.getInt("count", 0)

 

 

SharedPreferences의 데이터 삭제하기

remove()와 clear()를 호출하면 SharedPreferences 내의 데이터를 삭제할 수 있다.

remove()는 특정 데이터를 삭제하는 것이고 clear()는 해당 SharedPreferences 파일의 모든 데이터를 삭제한다.

remove()에는 Key Parameter가 들어간다. 어떤 Key를 가진 데이터를 삭제할 것인지, Key를 넣어주면 된다.

clear()에는 Parameter가 필요없다.

 

코드 예시

remove()

val spf : SharedPreferences = context.getPreferences(Context.MODE_PRIVATE)
val editor = spf.edit()
editor.remove("count")
editor.apply()

 

clear()

val spf : SharedPreferences = context.getPreferences(Context.MODE_PRIVATE)
val editor = spf.edit()
editor.clear()
editor.apply()

데이터를 변경하고 나서는 commit() 혹은 apply()를 해줘야한다.

 

 

commit()이랑 apply()의 차이는 몰랐는데, 큰 차이가 있었다는 것을 깨달았다.

로그인된 user의 ID 말고도 다른 초기값 지정할 때 SharedPreferences를 사용해봐야 겠다.

그리고 SharedPreferences와 자주 함께 사용하는게 있는데, KeyStore이다.

KeyStore는 토큰이나 비밀번호과 같은 중요 정보를 SharedPreferences에 저장할 때 사용된다.

중요 정보의 난독화를 가독화하게 하는 것이 Key인데, 이러한 Key를 추출하기 어렵게 만드는 것이 KeyStore이다.

다음에는 KeyStore에 대해서도 다루어보겠다.

 

참조

 

'Android > etc' 카테고리의 다른 글

[Android] Fragment 생명 주기  (0) 2022.06.25
[Android] Jetpack  (0) 2022.06.21
[Android] Glide 라이브러리의 사용  (0) 2022.06.11
[Android] Handler 개념  (0) 2022.06.07
[Android] Fragment  (0) 2022.06.01
Comments