보통 회사에서는 피그마를 사용해서 디자이너와 협업을 진행하게 된다.매번 비슷한 프로세스인데, 항상 느낀 건 리소스 다운로드가 번거롭다는 문제가 있다는 것이였다. 문제 도출프로젝트/디자이너 마다 이미지/압축파일/아이콘을 제공하는 방법들이 다르긴 하지만, 보통 아래의 과정을 거쳐 프로젝트에서 사용할 수 있게 된다.다운로드압축해제(zip 파일의 경우)이름 변경res/drawable로 이동위와 같은 비효율적인 과정이 반복적으로 발생해서 이런 불편함을 개선하고 싶었다.정리해 보면,피그마에서 다운로드 받는 png/jpg/jpeg/svg 파일의 이름이 규칙적인 패턴을 가지지만 제각각이다.심지어 zip 파일은 중첩된 폴더 구조로 되어 있어 IDE로 옮기는 과정이 복잡하고 비효율적이다.resource manager를 사..
object TimeConverter { /** * KMP 용 date & time 변환을 위한 라이브러리, kotlinx-datetime * * 오픈 API: openweathermap.org * * ``` * "timezone":"America/Chicago", * "timezone_offset":-18000, * "current":{ * "dt":1684929490 * . . . * } * ``` * * 1. UTC 타임 포맷을 사용하는 경우, 1000으로 나누는 이유 * 2. TimeZone이란? * 2-1. TimeZone 변환 중 예외 발생 시 사용하는 FixedOffs..
한달전부터 Manifest-for-android-interview라는 책으로 북 스터디를 진행하고 있다.면접 질문 모음집? 같은 느낌의 책이고, 안드로이드 전반에 걸친 질문들이 수록되어 있는 책이다.android GDE이신 sky-doves 님이 집필하신 책인데, 난이도(깊이)는 중-중상 정도 되는 것 같다. 스터디를 진행하면서 아쉬웠던 점은 책에 적혀있는 지식들로만 스터디가 진행된다는 점이였다.중소기업 면접이라면 단순히 A가 무엇인가요?라고 묻고 끝나는 경우가 많겠지만,근거 있는 기술 사용을 중요하게 여기는 대기업들의 면접을 가게 될 경우에는 작은 주제라도 꼬리 질문이 깊이 들어올 수 있기 때문에 피상적인 학습은 오히려 면접 상황에서 독이 될 수 있다. 그래서 매 스터디 회차마다 공용 리포지토리에 고민..
안드로이드 UI 대세인 컴포즈를 사용할 때에는 좀 더 스테이블한 Coil 라이브러리를 사용한다.하지만 xml을 통해 뷰 시스템을 사용하는 경우에는 캐시 성능이 뛰어난 Glide를 사용하는데, 오늘은 Glide의 디스크/메모리 캐시가 내부적으로 어떻게 구현되어 있는지에 대해 살펴보고자 한다. 우선, Glide의 캐시는 크게 메모리 캐시와 디스크 캐시로 구성되어 있다.우리는 diskCacheStrategy() 메서드를 통해 디스크 캐시 전략을, isMemoryCacheable/skipMemoryCache 메서드 등을 통해 메모리 캐시 사용 여부를 설정할 수 있다. 0. 전체 이미지 로딩 과정ActiveResources 조회MemoryCache 조회DishCache 조회네트워크/파일 로딩Glide를 통해 이미..
우리는 서버 Api를 호출할 때, Kotlin 객체를 Json 객체로 직렬화해서 전송하고 Json 객체를 Kotlin 객체로 역직렬화해서 사용하게 된다. 왜 이런 과정이 필요한 걸까?제대로 된 이유를 알지 못한 채 당연한 듯 생각했던 이 과정을 뜯어보자. 객체를 직렬화해서 전달하는 이유그런 일련의 과정이 필요한 이유는, 객체는 단순히 메모리 상에서 변수와 포인터로 이루어진 무언가이기 때문이다.JVM 메모리 상의 어떤 객체는 다른 곳에서 사용할 수 없기 때문에, 컴포넌트 간의 데이터를 공유하거나 서버 통신, DB 저장 등을 위해서는 직렬화한 후 수신부에서 변환하여 해당 환경에서 사용할 수 있는 데이터로 직렬화해야 한다. 직렬화 과정에서는 객체를 독립적인 데이터 포맷인 Json, Xml, 바이트 스트림 등으..
1. Context안드로이드에서 Context는 어플리케이션 컴포넌트들과 안드로이드 시스템 사이의 인터페이스 역할을 한다.우리는 Context를 통해서 시스템과의 상호 작용부터 우리가 주로 사용하는 리소스, 어셋, 파일, 컴포넌트 시작, 시스템 서비스 접근, 권한 확인을 수행하게 된다. 2. Application context, Activity context✨ Application contextApplication 전체 생명주기 동안 유효한 context이다. Activity context처럼 UI와 관련된 속성을 포함하지는 않지만, 전역적으로 어플리케이션의 정보를 제공한다.AlarmManager, LocationManager를 사용할 때, Activity context를 사용하여 시스템 서비스와 연동할..
💡DI 패턴을 사용하는 이유안드로이드 진영에서 DI 패턴은 필수적으로 사용되는 디자인 패턴 중 하나이다.여기서 개발자들은 Dagger, Hilt, Koin와 같은 DI 툴들을 선택해서 도입하게 되는데, 난 첫 DI 라이브러리로 Hilt를 사용했고 아직까지도 Hilt만 사용해오고 있다. 모든 디자인 패턴이 그렇듯, DI 패턴은 결합도 감소, 테스트 용이성 향상, 유지보수성 증가, 보일러플레이트 감소를 목적으로 사용된다. 내 생각에 DI 패턴만큼 테스트 용이성 향상과 결합도 감소에 효과적인 디자인 패턴은 없다. 게다가 안드로이드처럼 프레임워크 클래스들의 생명주기를 신경써야 하는 환경에서 Hilt나 Dagger를 사용한 DI 패턴은 더더욱 중요하다. 객체를 생성/파괴하는 로직을 라이브러리 레벨에서 처리해주기..
p.s 이 글에서 R8과 R8 컴파일러는 같은 것을 지칭하며, D8과 R8은 친구지만 서로 다른 개념입니다.코틀린 코드는 코틀린 컴파일러를 통해 바이트코드로 컴파일되며, 이 바이트 코드를 R8 컴파일러가 최적화하고 D8 컴파일러가 DEX 파일로 변환한다.이후 앱 실행시에 AOT나 JIT 컴파일을 통해 네이티브 코드로 변환되어 실행되는 원리이다.Proguard나 R8은 개발자가 설정 파일 외에는 추가적으로 설정해야하는 것들이 적어서 Proguard나 R8의 차이점이나 변경점을 모르는 경우가 많다.실 개발 단계에서도 안드로이드 개발자들은 각 라이브러리나 Kotlin 프로젝트에 필요한 Proguard 설정을 제외하고는 구체적으로 알아볼 필요성을 느끼지 못한다. 많은 라이브러리들이 정상적인 동작을 위해, 난독화..
1. Drawable안드로이드의 Drawable API는 화면에 그래픽을 그리기 위한 추상화된 계층을 제공한다.Drawable은 BitmapDrawable, VectorDrawable , NinePatchDrawable , ShapeDrawable 등의 다양한 구현체들이 존재한다.지난 포스팅에서 Bitmap Drawable의 densityDpi별 대응을 위해 밀도별 스케일 펙터를 적용한 Bitmap을 사용한다고 했는데, 왜 사진이나 복잡한 이미지는 Vector Drawable로 사용하지 않는 지 의문이 들었다. 2. VectorDrawable주로 애플리케이션에서 사용하는 로고, 아이콘에 사용되는 Drawable 구현체이다.앞선 포스팅에서는 밀도 별 버전을 만들어서 해상도 별로 대응을 한다고 했는데, Ve..
1. 안드로이드의 해상도 대응안드로이드 기기들은 다양한 화면 크기를 가지고 있다. 어떤 기기에서는 인치당 160 픽셀을 사용하지만, 다른 기기에서는 480픽셀을 사용할 수 있다. 따라서 이런 차이를 고려하지 않는다면 이미지가 깨지거나 잘못된 크기로 보여질 수 있다. 이 같은 상황에 대응하기 위해 안드로이드에서는 View 간의 거리나 크기를 정의할 때 픽셀을 사용하지 않도록 권장하고 있다. 기기마다 픽셀 밀도가 다르므로 고정된 픽셀 값을 사용하면 기기의 크기에 따라 유동적으로 적용되지 않기 때문이다.안드로이드에서는 픽셀 대신 dp를 사용한다. 이는 Density-Independent Pixel의 약자로, 밀도 독립형 픽셀이다.표준 단위인 dpi를 기반으로 하여 중밀도(mdpi, 160dpi)를 기준으로 논..