[Android/Kotlin] 안드로이드 SharedPreferences 사용하기
이번 시간에는 SharedPreferences를 좀 더 효율적으로 사용하는 방법에 대해서 알아보겠습니다.
안드로이드 개발 시 SharedPrefereces를 활용하여 간단한 상태값을 저장하기도 합니다.
최초 로그인 여부, 현재 로그인 유저의 간단한 정보, 가장 최근에 선택했던 값 등 다양하게 활용할 수 있습니다.
아래예제는 회원정보를 저장하고 조회하는 모습입니다.
[build.gradle/app]
// Preference
implementation 'androidx.preference:preference-ktx:1.1.1'
[PreferenceHelper.kt]
object PreferenceHelper {
fun defaultPrefs(context: Context): SharedPreferences =
PreferenceManager.getDefaultSharedPreferences(context)
private inline fun SharedPreferences.edit(operation: (SharedPreferences.Editor) -> Unit) {
val editor = this.edit()
operation(editor)
editor.apply()
}
operator fun SharedPreferences.set(key: String, value: Any?) {
when (value) {
is String? -> edit { it.putString(key, value) }
is Int -> edit { it.putInt(key, value) }
is Boolean -> edit{ it.putBoolean(key, value) }
is Float -> edit { it.putFloat(key, value) }
is Long -> edit { it.putLong(key, value) }
else -> throw UnsupportedOperationException("Error")
}
}
@Suppress("UNCHECKED_CAST")
operator fun <T> SharedPreferences.get(key: String, defaultValue: T? = null): T {
return when (defaultValue) {
is String, null -> getString(key, defaultValue as? String) as T
is Int -> getInt(key, defaultValue as? Int ?: -1) as T
is Boolean -> getBoolean(key, defaultValue as? Boolean ?: false) as T
is Float -> getFloat(key, defaultValue as? Float ?: -1f) as T
is Long -> getLong(key, defaultValue as? Long ?: -1) as T
else -> throw UnsupportedOperationException("Error")
}
}
}
SharedPreferences를 관리하는 Helper클래스입니다.
코틀린에서는 배열이나 맵의 원소에 접근할 때 대괄호를 사용할 수 있습니다. 이를 인덱스 연산자라고 하며 이를 사용하기 위해서 operator set / operator get 을 만들어 주었습니다. 호출 시 타입에 따라서 저장하고 불러 올 수 있습니다.
확장함수 edit을 만들어 사용했습니다.
[SharedManager.kt]
class SharedManager(context: Context) {
private val prefs: SharedPreferences = PreferenceHelper.defaultPrefs(context)
fun saveCurrentUser(user: User) {
prefs["name"] = user.name
prefs["age"] = user.age
prefs["email"] = user.email
prefs["password"] = user.password
prefs["isMarried"] = user.isMarried
}
fun getCurrentUser(): User {
return User().apply {
name = prefs["name", ""]
age = prefs["age", 0]
email = prefs["email", ""]
password = prefs["password", ""]
isMarried = prefs["isMarried", false]
}
}
}
set, get을 import하지 않으면 에러가 발생합니다.
import com.reachfree.enhancedsharedpreferences.PreferenceHelper.set
import com.reachfree.enhancedsharedpreferences.PreferenceHelper.get
[User.kt]
data class User(
var name: String? = null,
var age: Int? = 0,
var email: String? = null,
var password: String? = null,
var isMarried: Boolean? = false
)
[MainActivity.kt]
class MainActivity : AppCompatActivity() {
private var _binding: ActivityMainBinding? = null
private val binding get() = _binding!!
private val sharedManager: SharedManager by lazy { SharedManager(this) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnSave.setOnClickListener {
// validate 생략
val currentUser = User().apply {
name = binding.edtName.text.toString().trim()
age = binding.edtAge.text.toString().toInt()
email = binding.edtEmail.text.toString().trim()
password = binding.edtPassword.text.toString().trim()
isMarried = binding.switchIsMarried.isChecked
}
sharedManager.saveCurrentUser(currentUser)
}
binding.btnSearch.setOnClickListener {
val currentUser = sharedManager.getCurrentUser()
val result = "name: ${currentUser.name} \n" +
"age: ${currentUser.age} \n" +
"email: ${currentUser.email} \n" +
"password: ${currentUser.password} \n" +
"isMarried: ${currentUser.isMarried}"
binding.txtResult.text = result
}
}
override fun onDestroy() {
super.onDestroy()
_binding = null
}
}
[activity_main.xml]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context=".MainActivity">
<EditText
android:id="@+id/edt_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Name"
android:importantForAutofill="no"
android:inputType="textCapSentences" />
<EditText
android:id="@+id/edt_age"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Age"
android:importantForAutofill="no"
android:inputType="number" />
<EditText
android:id="@+id/edt_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Email"
android:importantForAutofill="no"
android:inputType="textEmailAddress" />
<EditText
android:id="@+id/edt_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="password"
android:importantForAutofill="no"
android:inputType="textPassword" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:text="Are you Married?"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Switch
android:id="@+id/switch_is_married"
android:gravity="end"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<Button
android:id="@+id/btn_save"
android:text="저장하기"
android:layout_marginTop="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_search"
android:text="조회하기"
android:layout_marginTop="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:text="현재 유저"
android:layout_marginTop="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/txt_result"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
'기리's Android 이야기' 카테고리의 다른 글
[Android/Kotlin] 안드로이드 Single Click 구현하기 feat. 두번 클릭 방지... (2) | 2021.01.22 |
---|---|
[Android/Error] 안드로이드 Caused by: java.lang.NullPointerException: Missing required view with ID: ~~~~~ (3) | 2021.01.21 |
[Android/Kotlin] 안드로이드 로또 당첨번호 조회하기(2) (4) | 2021.01.19 |
[Android/Kotlin] 안드로이드 로또 번호 생성하기(1) (1) | 2021.01.17 |
[앱소개/로또앱] 넘버원로또 소개 (4) | 2021.01.17 |
댓글