728x90
SharedPreferences란
안드로이드 앱 개발을 진행하다 보면, 앱의 데이터들을 저장하여 관리해야 할 상황이 존재한다. 데이터의 양이 많거나 중요 데이터의 경우 서버나 DB에 저장해야겠지만, 간단한 설정 값이나 문자열 같은 데이터를 저장하기 위해 DB를 사용하기는 부담스럽기 때문에 SharedPreferences를 사용하는 것이 적합하다.
- 보통 초기 설정값이나 자동 로그인 여부 등 간단한 값을 저장하기 위해 사용
- Application에 파일 형태로 데이터를 저장한다.
- Application이 삭제되기 전까지 저장한 데이터가 보존된다.
- Key-value 방식
- xml 파일 형태로 데이터를 저장 (data/data/패키지명/shared_prefs/SharedPreferences
- 파일 형태로 저장되므로 너무 많은 데이터를 넣게 되면 메모리 예외가 나타날 수 있다
- 파일 형태로 저장되므로 메모리 손상의 위험에 영향이 갈 수 있다
- 보안에 취약하므로 보안이 요구되는 데이터들은 SharedPreferences로 저장하지 않는 것이 좋다
MODE | 의미 |
MODE_PRIVATE | 어플리케이션 내에서 사용 가능, 외부 어플리케이션에서는 사용 불가, default 값 |
MODE_WORLD_READABLE | 외부 어플리케이션에서 읽기 가능 (API 17부터 deprecated) |
MODE_WORLD_WRITEABLE | 외부 어플리케이션에서 쓰기 가능 (API 17부터 deprecated) |
SharedPreferences 사용해보기
데이터 저장하기
val sharedPreference = getSharedPreferences("sp1", MODE_PRIVATE)
val editor : SharedPreferences.Editor = sharedPreference.edit()
editor.putString("hello","안녕하세요")
editor.putString("good bye","안녕히 가세요")
데이터 삭제하기
val sharedPreference = getSharedPreferences("sp1", MODE_PRIVATE)
val value1 = sharedPreference.getString("hello", "데이터 없다1")
val value2 = sharedPreference.getString("good bye", "데이터 없다2")
Log.d("key-value", "Value 1 : " + value1)
Log.d("key-value", "Value 2 : " + value2)
데이터 불러오기
val sharedPreference = getSharedPreferences("sp1", MODE_PRIVATE)
val editor = sharedPreference.edit()
editor.remove("hello")
// 전체 삭제는 editor.clear()
editor.commit()
SharedPreferences 를 이용하여 자동 로그인 구현하기
Data -> Object DBModule
SharedPreferences 싱글턴 생성
@Singleton
@Provides
@Named("auth")
fun provideEncryptedSharedPreferences(
@ApplicationContext context: Context
): SharedPreferences {
val masterKeyAlias = MasterKey.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
return EncryptedSharedPreferences.create(
context,
"auth",
masterKeyAlias,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
}
Data -> AuthRepositoryImpl
첫 로그인 시 해당 기기 안드로이드 앱에 아이디와 비밀번호가 저장
override suspend fun signIn(userName: String, password: String): Result<Unit> {
return try {
localDataSource.setData(Login(userName = userName, password = password))
userDao.getUserByNameAndPassword(name = userName, password = password)
Result.success(Unit)
} catch (e: Exception) {
e.printStackTrace()
Result.failure(e)
}
}
Data -> AuthLocalDataSourceImpl
SharedPreferences에 대한 기본적인 사용 메서드
class AuthLocalDataSourceImpl @Inject constructor(
@Named("auth") private val sharedPreferences: SharedPreferences
) : AuthLocalDataSource {
private var data: Login? = null
override fun hasData(): Boolean {
return getData() != null
}
override fun getData(): Login? {
// 이미 전에 데이터를 읽어 값이 있는 경우에는 곧바로 데이터를 반환한다.
if (data != null) {
return data
}
val json = sharedPreferences.getString(AUTH_LOCAL_DATA_PREFS_KEY, null) ?: return null
data = Gson().fromJson(json, Login::class.java)
return data
}
override fun setData(loginData: Login) {
data = loginData
val json = Gson().toJson(loginData)
sharedPreferences.edit().putString(AUTH_LOCAL_DATA_PREFS_KEY, json).apply()
}
override fun clear() {
data = null
sharedPreferences.edit().remove(AUTH_LOCAL_DATA_PREFS_KEY).apply()
}
Data -> AuthRepositoryImpl
이전에 로그인한 기록이 있다면 True, 아니라면 false
override suspend fun checkLoggedIn(): Result<Boolean> {
return try {
if (localDataSource.hasData()) {
Result.success(true)
} else {
Result.success(false)
}
} catch (e: Exception) {
Result.failure(e)
}
}
Presentation -> LoginViewModel
일전에 로그인했던 기록을 ViewModel UiState에 체크
private fun loggedIn() {
viewModelScope.launch {
val result = authRepository.checkLoggedIn()
Log.d("checkLoggedIn", result.toString())
if (result.isSuccess) {
_uiState.update {
it.copy(isLoggedIn = result.getOrNull()!!)
}
} else {
_uiState.update {
it.copy(
userMessage = R.string.login_fail,
isLoading = false
)
}
}
}
}
Presentation -> LoginActivity
이미 로그인한 적이 있다면 바로 다음 화면으로 넘어가기
private fun updateUi(uiState: LoginUiState) {
if (uiState.isLoggedIn) {
navigateMainActivity()
}
728x90
'Android > Study' 카테고리의 다른 글
[Android] DIP에 대해서 공부하자 (0) | 2024.06.09 |
---|---|
[Android] A RecyclerView with multiple item types in Kotlin에 대해서 공부하자 (0) | 2024.06.09 |
[Android] runOnUiThread()에 대해서 공부해보자 (0) | 2024.06.01 |
[Android] onNewIntent()에 대해서 알아보자. (0) | 2024.04.20 |
[Android] OkHttp에 대해서 공부해보자. (feat. Refrofit) (0) | 2024.04.20 |