https://medium.com/@dugguRK/android-security-best-practices-494a84bed004
명시적으로 https url 사용
인증서 고정 사용: CA 시스템에만 의존하지 않고 신뢰할 수 있는 인증서를 앱에 등록
EncryptedSharedPreferences 사용
암호화 된 파일 저장소에 저장: SQLCipher 등
OAuth/JWT
Role-Based access control
Session handling
SQL injection 방지를 위해 parameterized query나 prepared statement 사용
Multi-factor authentication
최신 버전이나 안정화 버전 확인
키 저장소 시스템: https://developer.android.com/privacy-and-security/keystore?hl=ko
권한이나 intent 접근 등
Log 등에 민감정보는 보여주지 않도록
https://medium.com/@ranjeet123/empowering-android-viewmodels-mastering-savedstatehandle-for-seamless-state-persistence-c1ea8af3ca08
안드로이드 공식: https://developer.android.com/topic/libraries/architecture/viewmodel/viewmodel-savedstate?hl=ko
ViewModel로 configuration change 시 앱의 정보는 복구할 수 있지만, 시스템에서 유발된 프로세스 종료같은 경우는 SavedStateHandle을 사용해야 한다.
SavedStateHandle은 AAC 라이브러리의 일부로 ViewModel에서 영구적 상태 처리를 위해 설계되었다. Key-value 쌍으로 데이터를 관리하며 config change나 프로세스 종료 시에도 보존 가능하다.
class SavedStateViewModel(private val state: SavedStateHandle) : ViewModel() {
val filteredData: LiveData<List<String>> =
savedStateHandle.getLiveData<String>("query").switchMap { query ->
repository.getFilteredData(query)
}
val filteredData: StateFlow<List<String>> =
savedStateHandle.getStateFlow<String>("query")
.flatMapLatest { query ->
repository.getFilteredData(query)
}
// from 2.5.0 compose state supported
var filteredData: List<String> by savedStateHandle.saveable {
mutableStateOf(emptyList())
}
fun setQuery(query: String) {
withMutableSnapshot {
filteredData += query
}
}
}