Android

· Algorithm
- 카테고리라는 테이블이 존재하고, 하위에 Book이라는 데이터가 리스트로 들어가는 구조가 있다. - 그리고 이 Book 또한 다른 테이블이고, 카테고리의 id를 외래키로 참조한다. - 카테고리의 id가 DB에 저장된 이후 업데이트되는 값이라 사실상 카테고리가 먼저 저장되지 않는 이상, Book 데이터가 저장될 수가 없는 상황이다. - 서비스에서는 매 동기화로 수신받은 카테고리가 DB에 존재할 경우에는 굳이 다시 DB 업데이트 로직을 진입하지 않는다. - 하지만 여기서 문제가... 카테고리는 제대로 저장되었어도 다음 Book 데이터 처리과정에서 사용자가 앱을 강제 종료하거나 어떠한 이유로 예외가 발생하여 동기화 상태가 완료되지 못한다면 카테고리 데이터만 남고, Book 데이터는 아무리 다시 동기화를 해도..
· Algorithm
- 클린 아키텍처에서 UseCase는 단일 책임 원칙 하에 앱에서 실행되는 비즈니스 프로세스를 캡슐화하는 역할을 한다. - UseCase를 구성함으로써 ViewModel의 역할을 명확히 할 수 있고, UseCase는 변경을 최소화 한 채 관심사를 분리하고, Activity 뿐만 아니라 View, Widget에서 즉시 사용 가능한 이점도 있다. - 근데 사이드 프로젝트에서 UseCase를 구성하고 관리하다 보니.. UseCase의 역할이 단순히 전달 정도로 밖에 안 되는 부분들이 많았다.class GetDestinationUseCase( private val repo: SettingsRepository) { operator fun invoke(): Flow = repo.getDestination..
- 갑자기 아래와 같은 경고 안내를 플레이 콘솔로 전달받았다.- 어떤 디바이스나 OS(특히 Android, iOS, 임베디드 환경)에서는 기본 페이지 크기가 16KB일 수 있다. 그래서 범용성을 위해 해당 앱이 여러 환경에서도 문제없이 동작할 수 있도록 접근 방식을 조정해야 한다는 것이다. - 첫 번째로 확인해 볼 만한 요소는 AGP 업그레이드다. 8.5.2 버전 이상으로 업데이트해 주어야 대응이 된다고 한다. - Tools의 AGP Upgrade Assistant를 사용하면 최신화 가능하다. - 두 번째로는 사용되는 라이브러리 조사다. 보통 Room, Coroutine, Compose 같은 자체 라이브러리에는 네이티브(. so) 코드가 포함되지 않아서 괜찮은데, 써드파티 라이브러리들은 사용하고 있을 가..
- 한동안 OOM 방지를 위한 작업들을 진행했는데, 여전히 OOM Crashlytics 보고가 끊이지 않았다. - 사용자 로그 및 계정 접속 테스트를 통해 알아낸 결과, 서버로부터 대량의 데이터를 수신받고 로컬 DB에 업데이트하는 시점에 OOM이 가장 빈번하게 발생하는 것으로 파악되었다. - 현재 서버와 클라이언트는 페이징 방식으로 List 구조의 데이터를 수신받고 로컬 DB에 저장하는데, 최근에 내가 동기화 로직을 리팩터링 하면서 Retrofit Call Response Type을 페이징과 관련된 데이터들 및 중간 매핑 리스트 타입을 포함한 data class로 등록한 시점부터가 문제였다.): Calldata class GetDataWithPageResult( val datas: List, ..
- Compose에서는 이미 렌더링 된 UI를 갱신하기 위해 상태 변경이 일어날 때마다 필요한 부분들을 다시 그리는 Recomposition이라는 메커니즘을 사용한다. - 리컴포지션은 상세하게 Composition -> Layout -> Drawing 세 가지 단계를 거친다. - 리컴포지션이 발생하면 Compose는 Composition 단계부터 새롭게 시작하며, 여기서 컴포저블 노드는 UI 변경 사항을 Compose Runtime에 알리고, 업데이트된 UI가 최신 상태를 반영하도록 보장한다. - 리컴포지션이 발생하는 조건은 다음과 같다.1. 매개변수에 변경이 발생했을 때2. 상태 변경이 관찰되었을 때 - Composition의 주요 작업• @Composable 함수 실행• UI 트리 생성 및 업데이트..
- Jetpack Compose는 개발자가 상태 변경 시 UI를 어떻게 업데이트할지를 나타내는 것이 아닌, 특정 상태에서 UI가 어떻게 보여야 하는지를 설명하는 선언적 UI 프레임워크의 특성을 가지고 있다. - 이는 개발자가 뷰를 데이터의 변화에 따라 수동으로 업데이트해야 하는 명령형 접근 방식과는 차이가 있는 것이다. - 예를 들어 서버로부터 어떤 데이터가 내려왔고, 그 데이터를 UI에 반영해 주려면 UI 레벨에서는 API 호출이 완료된 시점을 체크하여 refresh() 함수를 구현해서 재호출 해야 할 수 있다. - 하지만 Compose의 경우에는 데이터 자체를 State로 관찰하여 즉시 시스템이 UI에 반영할 수 있도록 한다. 선언형 UI 특징- 상태 주도 UI : 시스템은 각 컴포넌트의 상태를 추적..
- SQLite는 SQLiteOpenHelper라는 DB 초기화 및 생성 담당자를 갖고 있다. - onCreate(), onOpen(), onUpgrade() 등의 메서드가 있는데, 여기서 onUpgrade()를 통해 마이그레이션 작업 수행이 가능하다. - 마이그레이션 단계 구분을 위해서 DB 버전을 생성해주어야 한다. 마이그레이션 시, 해당 버전 값을 +1 하는 것을 잊지 말자private static final int DATABASE_VERSION = 11;public static synchronized DBHelper getHelper(Context context) { if (instance == null) instance = new DBHelper(context); return inst..
- 자사 앱 플레이스토어 이동 링크를 웹뷰에서 클릭했는데 다음과 같은 화면이 나왔다.- 웹뷰가 intent:// 스킴을 이해하지 못해서 발생하는 문제다.- 안드로이드 WebView는 http://, https://는 기본 지원하지만, intent:// 같은 커스텀 스킴은 직접 처리해줘야 한다. - 웹뷰 클라이언트를 다음과 같이 수정해 주면 된다. URI_INTENT_SCHEME를 사용해서 대응해 주던지 아니면 외부로 플레이스토어를 열어주던지의 결정이 필요하다.webView.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Bo..
- 개념적인 것들을 정리하는 것과 별개로 그날 하루 '개발자 활동'에 대해 무지성으로 기록하는 Dev Diary임1. 앱 데이터 복원 문제- 언제부턴가 앱을 재설치하는데, 사용자 prefs 데이터가 자동으로 복원됨 - 그로 인해 자동으로 로그인까지 진행해 버리는데, token 부분은 데이터가 존재하지 않아 계속 유저 인증 오류 발생android:allowBackup="true"- 안드로이드 자동 백업 옵션을 켜두면 구글 드라이브 기반으로 사용자 설정에 따라 앱 데이터를 복원하는데 이것이 영향을 주는 것으로 판단 - 그러나 우리 서비스는 따로 복원하고픈 prefs.xml 파일을 지정하고 있었다. 그런데도 발생.. - 추가로 확인해 보니 앱에서 사용 중인 어떤 라이브러리들이 백업 기능에 영향을 주고 있었고..
- 코틀린에서 코루틴은 CoroutineContext라는 실행 맥락 안에서 동작한다. - Context는 여러 요소(Job, Dispatcher 등)를 포함하고 있으며, 그중에서도 Dispatcher는 코루틴이 어떤 스레드에서 실행될지를 결정하는 중요한 역할을 한다. - 먼저, 코루틴의 Dispatcher에는 다음과 같은 종류가 있다.Dispatchers.Main설명: 안드로이드 메인(UI) 스레드에서 실행.용도: UI 업데이트, Toast, View 조작, LiveData/StateFlow 수집 등.주의: 긴 연산이나 I/O를 여기서 하면 ANR 발생 가능.CoroutineScope(Dispatchers.Main).launch { textView.text = "UI 업데이트" }2️⃣ Dispatche..
SeungYong.Lee
'Android' 태그의 글 목록