안드로이드 스튜디오를 업데이트하고 빌드하는데, 갑자기 위와 같은 오류가 발생했다.명확한 원인을 알기 힘들어서 여러 가지 삽질을 했다... 일단 Settings - Gradle에서 현재 사용 중인 자바 버전을 맞춰줬다. 그리고 ilbs.versions.toml 파일에서 코틀린 버전도 업데이트했다.[versions]accompanistSystemuicontroller = "0.36.0"activityComposeVersion = "1.8.0-alpha07"agp = "8.5.0"biometric = "1.2.0-alpha05"converterGson = "2.9.0"glanceAppwidget = "1.1.1"hiltAndroid = "2.44"kotlin = "1.9.23"coreKtx = "1.12.0"..
- 운영 중인 서비스 로직은 서버로부터 새로운 리소스를 받으면 항상 고정된 경로의 로컬 파일 Storage 경로로 저장을 하고, Glide로 해당 이미지 리소스를 렌더링 하고 있었다. - 그런데 어느날 서버로부터 변경된 리소스를 내려받아도 렌더링 단계에서 해당 리소스가 갱신되지 않는 문제를 발견. - 분명히 로컬 저장 단계까지 변경된 리소스가 저장되는 것까지 확인했으나 원인은 Glide 동작 설정에 있었다. - Glide는 기본적으로 캐싱 기능을 가진다. 디스크 캐시와 메모리 캐시를 활용하여 이미지를 빠르게 로드하고 불필요한 네트워크 요청을 줄이는 기능을 가지고 있다.1. 메모리 캐시 (Memory Cache)이미 로드된 이미지를 RAM에 저장하여 빠르게 다시 불러올 수 있도록 함앱이 종료되거나 메모리가..
- 이런 구조의 TimePicker를 가진 Sheet가 존재하는데, TimePicker의 각 hour, minute 부분은 별도의 EditText로서 사용자의 포커스 온이 가능합니다. - 그런데, 키보드에서 '다음' 또는 '확인' 버튼을 누르지 않는 이상 전체 TimePicker에 해당 값이 전달되지 않으면 UI 및 데이터 업데이트에 문제가 있었습니다. - 사실 아래 설정을 통해 아예 사용자 입력을 비활성화시키고 스크롤만 가능하게 할 수도 있습니다. android:descendantFocusability="blocksDescendants" - 하지만 최대한 사용자의 입력을 존중(?)하기 위해 사용자가 Sheet를 닫을 시, 각 EditText의 포커스 상태를 검사하고 값을 가져오는 처리를 진행했습니다. ..
Application 클래스란?Application 클래스는 Android 애플리케이션의 전반적인 상태를 관리하는 기본 클래스입니다.앱이 실행될 때 가장 먼저 생성되며, 앱이 종료될 때까지 유지됩니다. - 싱글톤처럼 동작하며, 어디서든 접근 가능 - 앱의 생명 주기 관리- 앱 전역에서 공유해야 하는 데이터(예: SharedPreferences, DI Container, Theme, Locale 등)를 관리- 의존성 주입(Dagger/Hilt), Firebase 초기화, Crashlytics 설정 등 각종 초기설정을 여기서 진행 - 반드시 Manifest에 선언해주어야 한다.
memoText.text = Html.fromHtml(timeBlock.description?.replace("\n", ""))- 위와 같은 코드가 존재한다. Html.fromHtml()을 사용하여 HTML 태그를 포함한 문자열을 Spanned 형태로 변환하여 TextView에서 HTML 렌더링을 할 수 있게 하는 코드이다. - replace("\n", "")를 통해 개행(\n)을 태그로 변환하여 HTML에서 줄 바꿈을 유지하도록 한다. - 그런데, 사용자가 만일 EditText에 이런식으로 입력해 버리면 통째로 사라져 버린다. 그래서 입력된 문자를 HTML 엔티티로 변환하는 과정이 필요하다. fun fromHtmlSafe(source: String?): Spanned { val safeTex..
- height를 코틀린에서 wrap_content로 변경해 봅니다.- adjustViewBounds는 이미지뷰를 경계선에 따라 조정할지 여부입니다. background에 커스텀 레이아웃을 사용할 때 유용합니다.val layoutParams = binding.previewImg.layoutParamslayoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENTbinding.previewImg.layoutParams = layoutParams
먼저 둥근 테두리 모양에 해당하는 XML을 구성해 줍니다. ImageView 자체의 background로 지정해 주고. clipToOutline을 true로 해줍니다.clipToOutline : 뷰의 개요를 사용하여 뷰의 내용을 클립 해야 하는지 여부
AAC(Android Architecture Components)란?AAC는 안드로이드 앱 개발을 쉽게 만들기 위해 제공되는 아키텍처 구성 요소앱 개발 시 라이프사이클 관리, 데이터 저장, UI 상태 관리 등을 표준화MVVM 패턴과 함께 사용하면 유지보수성과 확장성이 뛰어난 앱을 개발 가능AAC 주요 구성 요소ViewModel : UI 데이터를 저장하고 라이프사이클을 관리LiveData : 데이터 변경을 감지하고 UI에 반영Room : SQLite DB를 관리하는 ORM 라이브러리LifeCycle : Activity / Fragment의 라이프사이클을 관리ViewModel- UI 데이터를 관리하고 라이프사이클을 유지하는 역할- ViewModel을 사용하면 화면 회전 시 데이터가 유지됩니다.class My..
- 앱에서 활용하던 GIF 파일들이 많아지면서 용량이 증가하고 관리 비용에도 점점 문제가 생기기 시작했습니다. - 이에 따라 애니메이션 재생에도 뒤처지지 않고, 용량도 더 적은 WebP 파일을 활용하기로 결정했습니다. - Glide를 활용해 렌더링을 진행했는데, 사실 기존 GIF 파일 재생 방법과 큰 차이가 없습니다. 같은 로직으로 두 가지 종류 파일 모두 호환 가능합니다. - WebP가 GIF보다 나은 점들은 아래와 같습니다. - raw 폴더 하위에 webp 파일을 넣고, Uri 경로를 구성해주어야합니다.val resourceUri = Uri.parse("android.resource://${context.packageName}/${R.raw.test}") - 해당 Uri 기반으로 로드해 줍니다. ur..
YIQ란?YIQ는 NTSC TV 신호에서 사용된 색 공간(Color Space)아날로그 TV 방송에서 흑백 TV와 컬러 TV를 동시에 지원하기 위해 설계됨RGB보다 밝기와 색상 정보가 분리되어 있음 → 밝기 기반 이미지 처리에 유용Y(Luminance, 밝기), I(In-phase, 색상 성분), Q(Quadrature, 색상 성분)로 구성됨YIQ의 구성 요소- Y (Luminance, 밝기) : 이미지의 밝기(명도) 정보 (흑백 TV에서도 사용 가능)- I (In-phase, 색상 차 성분 1) : 주황색(Orange) ↔ 청록색(Cyan) 색상 정보- Q (Quadrature, 색상 차 성분 2) : 자홍색(Magenta) ↔ 녹색(Green) 색상 정보YIQ와 RGB 변환 공식- RGB → YIQ ..