안드로이드 12) SharedPreferences

밍나·2022년 1월 20일
0

Android

목록 보기
12/36

Concepts of Persistence

1. 데이터 저장

  • 일반적으로 데이터는 안드로이드 애플리케이션과 서버 애플리케이션이 네트워크 통신을 하며 데이터를 주고 받으며 서버 사이드 DB에 저장을 함
  • 이 포스트에서는 서버 사이드에 데이터를 저장하는 것이 아닌 애플리케이션 자체에서(로컬에서) 애플리케이션이 종료되어도 사라지지 않고 영속적으로 저장하는 데이터를 다룰 것
    • File Read/Write : 이미지 데이터
    • Sharedpreference : 이미지 외 데이터
    • Database : 이미지 외 데이터

2. File

  • 자바 API로 File Read/Write
    • File : 파일 및 디렉토리를 지칭하는 클래스
    • FileInputStream / FileOutputStream : 파일에서 바이트 스트림(이미지)으로 데이터를 읽거나 쓰는 클래스
    • FileReader / FileWriter : 파일에서 문자열 스트림으로 데이터를 읽거나 쓰는 클래스

  • 파일이 저장되는 곳을 내장 메모리 공간과 외장 메모리 공간으로 구분
    • 내장 메모리 공간 : 앱만 이용할 수 있는 저장 공간
    • 외장 메모리 공간 : 여러 앱에서 같이 이용할 수 있는 저장 공간
  • 외장 메모리 공간은 앱별 저장 공간과 공용 저장 공간으로 구분
    • 앱별 저장 공간 : 특정 앱만을 위한 저장 공간
    • 공용 저장 공간 : 여러 앱이 공유할 수 있는 저장 공간
// filesDir : 내장 메모리 공간 지칭
val file = File(filesDir, "test.txt")
val writeStream: OutputStreamWriter = file.writer()
writeStream.write("hello world")
writeStream.flush
  • 내장 메모리 공간이란 앱이 설치되면 시스템에서 자동으로 할당하는 메모리 공간
  • 앱의 패키지명(식별자)으로 폴더를 만들어 주며 이 폴더가 이 앱의 내장 메모리 공간

SharedPreferences

1. SharedPreferences

  • 데이터를 key-values 형태로 저장(Map 객체)
  • 내부적으로 내장 메모리의 앱 폴더에 XML 파일로 데이터가 저장

2. Preferences를 얻는 방법
1) Activity.getPreferences(int mode)

  • 하나의 액티비티를 위한 데이터 저장을 목적
  • 이 함수를 이용한 액티비티 클래스명으로 XML 파일명이 만들어 짐(매개변수로 파일명을 따로 주지 않아도 됨)

2) Context.getSharedPreferences(String name, int mode) - common

  • 앱 전체의 데이터를 key-values 형태로 저장
val sharedPref = getSharedPreferences("my-prefs", Context.MODE_PRIVATE)

3. SharedPreferences 사용 방법
1) 데이터 저장

  • SharedPreferences.Editor 객체를 SharedPreferences의 edit() 함수로 획득
  • 데이터를 저장하기 위해서는 SharedPreferences.Editor 클래스의 put()함수를 이용
    • putBoolean(String key, boolean value)
    • putInt(String key, int value)
    • putFloat(String key, float value)
    • putLong(String key, long value)
    • putString(String key, String value)
  • commit() 하는 순간 저장

2) 데이터 획득

  • 데이터를 획득하기 위해서는 SharedPreferences의 getter함수를 이용
    • getBoolean(String key, boolean defValue)
    • getInt(String key, int defValue)
    • getFloat(String key, float defValue)
    • getLong(String key, long defValue)
    • getString(String key, String defValue)

Settings XML

1. Settings XML

  • 앱의 환경설정을 위해서는 Activity에서 event가 발생했을 때 어떤 정보를 영속적으로 저장하면 됨
  • settings xml은 이런 앱의 환경설정 자동화를 목적으로 함

1. Settings XML 사용 방법
1) API 버전에 따른 라이브러리 설정

  • API Level 29 이전 버전에서는 PreferenceFragment을 이용
  • API Level 29 버전부터는 AndroidX Preference를 이용할 것을 권장
implementation 'androidx.preference:preference-ktx:1.1.1'

2) res/xml 폴더에 설정과 관련된 xml 파일 작성(settings.xml)

  • 루트 태그가 <PreferenceScreen>
  • 태그를 이용해 각각의 설정 항목 준비
    • key 속성의 값과 설정 값으로 Preference에 key-values 형태로 저장
    • title 속성은 화면에 출력되는 문자
  • 태그 종류
    • PreferenceScreen : 설정 화면 단위, 중첩 가능하며 중첩된 내용은 별도의 홤녀에 나옴
    • PreferenceCategory : 설정 여러 개를 시각적으로 묶어서 표현
    • CheckboxPreference : 체크박스가 나오는 설정
    • EditTextPreference : 글 입력을 위한 설정
    • ListPreference : 항목 Dialog을 위한 설정
    • MultiSelectListPreference : 항목 Dialog인데 체크박스가 자동 추가되어 여러 선택 가능
    • RingtonPreference : Rington 선택을 위한 설정
    • SwitchPreference : Switch를 이용한 설정
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
	<SwitchPreferenceCompat
    		app:key="notification"
        	app:title="Enable message notifications"/>
</PreferenceScreen>

3) xml 적용, PreferenceFragmentCompat을 상속받은 Fragment로 설정

  • 이 과정까지만 해주면 UI가 뜨고, 유저의 event를 받아 데이터를 저장하는 것까지 자동화 된다.
class SettingsFragment: PreferenceFragmentCompat() {
	override fun onCreatePreference(savedInstanceState: Bundle?, rootKey: String?) {
    		setPreferencesFromResource(R.xml.settings.rootKey)
    }
}

PreferenceFragmentCompat

1. PreferenceFragmentCompat

  • settings.xml에서 자동으로 해주는 것 외에 필요에 따라 제어하고 싶은 경우에 사용

1) 설정을 위해 사용한 태그에 해당되는 객체를 findPreference() 태그로 획득

<EditTextPreference
	android:key="id"
    android:title="ID 설정"
    android:isPreferenceVisible="false" />
val idPreference: EditTextPreference? = findPreference("id")
idPreference?.isVisible = true

2) 나 에 값 입력시 summary 값 변경

  • SimpleSummaryProvider 이용 : 유저가 입력한 값을 summary에 출력
soundPreference!!.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance())
  • SummaryProvider 하위 클래스 : 유저가 입력한 값이 아닌 개발자가 원하는 값을 출력하고 싶은 경우
idPreference?.summaryProvider =
	// 매개변수 preference에 유저 입력 값이 들어옴
	Preference.SummaryProvider<EditTextPreference> { preference ->
    		val text = preference.text
        	if(TextUtils.isEmpty(text)) {
        		"설정이 되지 않았습니다."
        	} else {
        		"설정된 ID 값은 $text 입니다."
        	}
    	}

3) 유저가 설정을 하기 위해서 화면을 터치하는 순간의 이벤트 처리

  • setOnPreferenceClickListener()을 이용해 이벤트 핸들러를 지정
idPreference?.setOnPreferenceClickListener {
	true
}

4) 유저가 설정 값을 변경한 순간의 이벤트 처리

  • Preference.OnPreferenceChangeListener을 이용 : 각 Preference 객체에 적용
  • SharedPreferences.OnSharedPreferenceChangeListener 이용 : 모든 설정 객체의 변경을 하나의 이벤트 핸들러에서 감지
// 설정 값이 newValue 변수로 넘어 옴
idPreference?.setOnPreferenceChangeListener { preference, newValue ->
	Log.d("preference", "preference key : ${preference.key}, newValue : $newValue")
    true
}
profile
🤗🤗🤗

0개의 댓글