- 개념적인 것들을 정리하는 것과 별개로 그날 하루 '개발자 활동'에 대해 무지성으로 기록하는 Dev Diary임
1. 앱 데이터 복원 문제
- 언제부턴가 앱을 재설치하는데, 사용자 prefs 데이터가 자동으로 복원됨
- 그로 인해 자동으로 로그인까지 진행해 버리는데, token 부분은 데이터가 존재하지 않아 계속 유저 인증 오류 발생
android:allowBackup="true"
- 안드로이드 자동 백업 옵션을 켜두면 구글 드라이브 기반으로 사용자 설정에 따라 앱 데이터를 복원하는데 이것이 영향을 주는 것으로 판단
- 그러나 우리 서비스는 따로 복원하고픈 prefs.xml 파일을 지정하고 있었다. 그런데도 발생..
- 추가로 확인해 보니 앱에서 사용 중인 어떤 라이브러리들이 백업 기능에 영향을 주고 있었고, 그에 따라 tools로 명시
- 그리고 fullBackupContent를 기존에는 사용했는데, SDK 버전을 올리면서 dataExtractionRules를 활용하도록 개선
https://developer.android.com/identity/data/autobackup?hl=ko
자동 백업으로 사용자 데이터 백업 | Identity | Android Developers
이 페이지는 Cloud Translation API를 통해 번역되었습니다. 자동 백업으로 사용자 데이터 백업 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 앱의 자동 백업은 A
developer.android.com
<?xml version="1.0" encoding="utf-8"?>
<data-extraction-rules xmlns:android="http://schemas.android.com/apk/res/android">
<cloud-backup>
<!-- 백업하고 싶은 것만 include -->
<include domain="sharedpref" path="last_login.xml"/>
</cloud-backup>
<device-transfer>
<include domain="sharedpref" path="last_login.xml"/>
</device-transfer>
</data-extraction-rules>
- 사용자 로그인 힌트 정도를 기억해 두는 prefs
<cloud-backup>
- 의미: 사용자가 Google 계정으로 백업할 때 포함/제외할 데이터를 정의
<device-transfer>
- 의미: 기기 간 데이터 전송 시 포함/제외할 데이터
- 그리고 서드파티 라이브러리에서 사용되는 것을 고려하여 tools를 기입해 주었다.
<application
android:allowBackup="false"
android:dataExtractionRules="@xml/tb_backup_rules"
tools:replace="android:allowBackup, android:dataExtractionRules"
...
/>
- 일단 데이터가 항상 복원되는 문제는 해결되었으나 dataExtractionRules는 디바이스 백업 설정을 통해 좀 더 확인이 필요해 보인다.
2. OOM 발생
- OOM이 계속 발생한다고 Crashlytics에 보고가 들어왔다.
- 프로파일러로 메모리 누수를 확인했을 때에는.. Splash 부분에서 한 군데밖에 없었고, 멤버 변수에 대한 onDestroy 처리를 강화해 주었다.
- 추가적으로 Coil을 통해 이미지 리사이징하는 부분이 있었는데, ImageLoader 컴포넌트 선언 시, 아래 두 가지 옵션을 추가했다.
- . allowRgb565(true) → 메모리 반절로 줄일 수 있음
- . crossfade(false) → 불필요한 애니메이션 bitmap 캐싱 줄임
- 그리고 서비스의 주요 캐시 데이터를 백그라운드에서 관리하는 Manager가 있었는데 이 부분 또한 최적화를 진행
- 기존에 캐시 데이터를 UI와 관련 깊은 StateFlow <Map <>> 타입으로 관리되고 있었는데, 이게 결국 UI로 직접 전파될 일도 없어서 동시성 프로세스에 적합한 ConcurrentHashMap으로 변경
- StateFlow 같은 경우 캐시 업데이트 시, 매번 새롭게 Map 객체를 생성해야 하니.. 부담이 될 거라고 생각하여 개선
- 그리고 생명주기에 따라 사용자가 앱을 종료시킬 경우에는 메모리에 절대 남지 않도록 모든 리소스를 해제
fun clear() {
fetchResult.clear()
reservedTask = null
currentTask = null
scope.coroutineContext.cancelChildren()
}
- 기존 버전에서의 프로파일을 확인해보니 특히 앱을 처음 시작하거나 전체 데이터를 갱신하는 순간 메모리 사용량이 치솟고 있었다.
- 위 절차들만이라도 진행하니 평균 500mb 대로 유지하고 앱 시작 상황에서 치솟는 상황은 어느 정도 대응한 듯?
- 그러나 여전히 Wepb 이미지를 렌더링 하는 과정 + 주변 블러 효과를 처리하는 과정에서 메모리 사용량이 급증하는 것이 보인다..