Android(98)
-
빌드 시간 최적화 과정 (30분 → 5분)
내가 회사에서 관리하는 프로젝트 중에 용량이 엄청 큰 프로젝트가 있다.이건 generate apk를 뽑으려면 무조건 30분의 시간이 소요되어 어려움을 많이 겪었다.그래서 build.properties 파일을 이용하여 빌드 시간을 최적화해보았다.원래 상황 (30분)Gradle이 매번 이랬음:"안녕하세요, 처음 뵙겠습니다!" → JVM 새로 시작 (10초)→ 모든 파일 하나씩 차례로 빌드 (25분) → 다 끝나면 메모리에서 삭제→ 다음 빌드 때 또 "처음 뵙겠습니다!" 반복...1단계: 메모리 증설 시도기존: org.gradle.jvmargs = -Xms192m -Xmx4096m -XX:MaxPermSize=256m수정: org.gradle.jvmargs = -Xms192m -Xmx8192m -XX:Max..
2025.09.05 -
왜 사진이 회전하지? Android EXIF 완벽 가이드
"분명 세로로 찍었는데 왜 가로로 보이지?" Android 개발자라면 한 번은 겪어봤을 이미지 회전 문제, EXIF로 해결해보자.EXIF란?EXIF (Exchangeable Image File format): 디지털 사진에 포함되는 메타데이터포함 정보카메라 정보 (제조사, 모델)촬영 설정 (조리개, 셔터속도, ISO)촬영 날짜/시간GPS 위치 정보이미지 회전 정보 ← 가장 중요!핵심 문제: 이미지 회전문제 상황*// ❌ 이렇게 하면 세로 사진이 가로로 보임*val bitmap = BitmapFactory.decodeFile(imagePath)imageView.setImageBitmap(bitmap)원인: 스마트폰 센서는 가로 방향이지만, 촬영 방향을 EXIF에만 저장. BitmapFactory는 이를 무..
2025.08.28 -
AsyncTask에서 RxJava로: Android 비동기 처리 현대화하기
Android 11(API 30)부터 AsyncTask가 deprecated 되었다.하지만 우리 회사 앱은 레거시 중에 초초초 레거시 앱 !!레거시 앱을 유지보수하다 보면 수백 개의 AsyncTask를 마주하게 되는데, 이를 어떻게 현대적인 방식으로 전환할까? 왜 AsyncTask는 deprecated 되었나?메모리 누수: Activity 참조를 잘못 관리하면 쉽게 메모리 누수 발생구성 변경 처리 어려움: 화면 회전 시 작업 관리가 복잡병렬 처리 제한: 기본적으로 순차 실행되어 성능 최적화 어려움RxJava로 전환하기Before: AsyncTask (순차 처리)private class DownloadVideoAsyncTask extends AsyncTask { @Override protecte..
2025.08.26 -
Activity launchMode 정리: singleTop vs singleTask 차이
앱을 배포하기 전 테스트하는 과정에서 갑자기 기존에 나지 않던 오류가 발생했다.Activity가 계속 겹겹이 쌓이는 현상.그쪽 소스코드는 고친 적이 없는데 무슨 일인가? 하나씩 히스토리를 따라 찾아가기 시작했고, AndroidManifest에서 단서를 발견했다.안드로이드 launchMode에서 singleTop과 singleTask는 Activity의 재사용 여부 Task 관리 방식에서 차이가 있다.이 사실을 모르는 나는 아무 생각 없이 이 부분을 고쳤고, Activity가 무한히 생성되는 이슈를 발견했다.singleTop동일 Task 안에서 이미 해당 Activity 인스턴스가 맨 위(top) 에 있으면 → 재사용맨 위가 아니면 → 새 인스턴스를 생성해서 위에 올림즉, "Top에 있으면 재사용, 아니면..
2025.08.19 -
Android에서 Activity 생성은 왜 비동기인가: 안드로이드 전환 아키텍처 정리
1. 안드로이드의 UI 스레드 모델Android 앱은 UI 스레드(Main Thread) 위에서 화면을 그림Activity 생성/삭제 같은 라이프사이클 이벤트도 메인 스레드에서 처리되지만, 이는 즉시 동기 처리가 아니라 메시지 큐 기반의 비동기 처리즉, "호출 → 바로 완료"가 아니라, 이벤트가 메시지 큐에 등록되고, 차례가 되면 실행2. 생성과 소멸의 흐름(1) 생성 과정startActivity() 호출 → 내부적으로 ActivityThread에 메시지를 보냄.Looper가 해당 메시지를 읽어 Activity 인스턴스 생성 → onCreate → onStart → onResume 순으로 호출.이 과정은 즉시 실행되는 것처럼 보이지만, 사실은 다음 UI 루프에서 처리(2) 소멸 과정finish() 호출 ..
2025.08.13 -
구조적 동시성을 위한 코루틴 스코프 가이드
안드로이드 Coroutines Scope 완전 가이드— GlobalScope, viewModelScope, supervisorScope 한 번에 정리했다코루틴을 쓰다 보면 어떤 Scope를 써야 할지 헷갈린 적이 많았다.특히 GlobalScope는 쓰면 안 된다고 해서 이유를 찾아봤고,viewModelScope, lifecycleScope, coroutineScope, supervisorScope까지 한 번에 정리해보았다.1. GlobalScope— 쓰면 안 된다고?생명주기와 무관해서 화면이 닫혀도 코루틴이 계속 실행되기 때문에 그 상태에서 죽은 UI에 접근하면 크래시가 난다.취소 전파가 없다. 부모가 사라져도 작업은 계속 돈다.추적이 힘들다. 누가 만든 Job인지 관리가 안 된다.❌ 화면 크래시 예시f..
2025.08.12