전체 글

개발/Android

[안드로이드] 난독화와 R8 컴파일러

p.s 이 글에서 R8과 R8 컴파일러는 같은 것을 지칭하며, D8과 R8은 친구지만 서로 다른 개념입니다.코틀린 코드는 코틀린 컴파일러를 통해 바이트코드로 컴파일되며, 이 바이트 코드를 R8 컴파일러가 최적화하고 D8 컴파일러가 DEX 파일로 변환한다.이후 앱 실행시에 AOT나 JIT 컴파일을 통해 네이티브 코드로 변환되어 실행되는 원리이다.Proguard나 R8은 개발자가 설정 파일 외에는 추가적으로 설정해야하는 것들이 적어서 Proguard나 R8의 차이점이나 변경점을 모르는 경우가 많다.실 개발 단계에서도 안드로이드 개발자들은 각 라이브러리나 Kotlin 프로젝트에 필요한 Proguard 설정을 제외하고는 구체적으로 알아볼 필요성을 느끼지 못한다. 많은 라이브러리들이 정상적인 동작을 위해, 난독화..

개발/Kotlin

[Kotlin] sealed class, enum class 바이트 코드 뜯어보기

오늘 포스팅 주제는 Kotlin의 유용한 기능인 sealed와 enum이다.둘 다 컴파일 타임에 타입 집합이 결정되어 타입 안전하고 when문을 exhaustive하게 함으로써 경우에 따른 명확한 처리 구문을 작성할 수 있도록 도와준다.오늘은 이 두 개념들의 역할을 넘어, 컴파일되었을 때의 차이점과 그로 인해 고려할 수 있는 것들에 대해 얘기해보고자 한다.1. sealed class코틀린의 sealed class는 모듈/패키지 외부에서 해당 클래스를 상속할 수 없도록 상속 가능 범위를 제한해서 클래스 계층 구조를 타입 안전하게 제공한다. 주로 여러 상태를 한가지 타입으로 다룸으로써 when문에서 모든 케이스를 명시적으로 처리하기 위해 사용된다.sealed class의 모든 하위 클래스는 컴파일 타임에 검..

개발

유연한 클린 아키텍처를 위해 고려해야 할 것들

약 1년 이상의 기간동안 회사에서 진행했던, 또는 사이드 프로젝트 팀에서 진행한 프로젝트들에 로버트 마틴의 클린 아키텍처를 적용해서 개발을 하고 있다.사실 진행한 여러 프로젝트들 중 굳이 클린 아키텍처를 적용할 필요가 없는 것들도 있었지만, 클린 아키텍처의 장단점을 지속적으로 경험함으로써 클린 아키텍처라는 개념을 딱딱하게 가져가기보다는 핵심 개념을 개발 과정에서 체득하기 위함이였다. 그렇게, 클린 아키텍처는 파고 들어갈수록 어떤 구체화된 하나의 아키텍처가 아니라, 더 유연하고 확장성 있는 개발을 위한 추상적인 개념들의 집합체로써 받아들이게 되었다.내가 클린 아키텍처를 좋아하는 이유도 어떤 고정적 구조를 가지는 이상적인 아키텍처라서 그렇다기보다는, 주니어 개발자인 나에게는 구조적 이점을 가져감으로써 소프트..

개발/Android

[안드로이드] Vector Drawable 변환 과정과 Bitmap(feat.dp를 사용하면 모든 화면에서 동일하게 보일까?)

1. Drawable안드로이드의 Drawable API는 화면에 그래픽을 그리기 위한 추상화된 계층을 제공한다.Drawable은 BitmapDrawable, VectorDrawable , NinePatchDrawable , ShapeDrawable 등의 다양한 구현체들이 존재한다.지난 포스팅에서 Bitmap Drawable의 densityDpi별 대응을 위해 밀도별 스케일 펙터를 적용한 Bitmap을 사용한다고 했는데, 왜 사진이나 복잡한 이미지는 Vector Drawable로 사용하지 않는 지 의문이 들었다. 2. VectorDrawable주로 애플리케이션에서 사용하는 로고, 아이콘에 사용되는 Drawable 구현체이다.앞선 포스팅에서는 밀도 별 버전을 만들어서 해상도 별로 대응을 한다고 했는데, Ve..

개발/Android

[안드로이드] 쉘 스크립트로 이미지를 dpi 폴더에 분류하기(feat.해상도 대응)

1. 안드로이드의 해상도 대응안드로이드 기기들은 다양한 화면 크기를 가지고 있다. 어떤 기기에서는 인치당 160 픽셀을 사용하지만, 다른 기기에서는 480픽셀을 사용할 수 있다. 따라서 이런 차이를 고려하지 않는다면 이미지가 깨지거나 잘못된 크기로 보여질 수 있다. 이 같은 상황에 대응하기 위해 안드로이드에서는 View 간의 거리나 크기를 정의할 때 픽셀을 사용하지 않도록 권장하고 있다. 기기마다 픽셀 밀도가 다르므로 고정된 픽셀 값을 사용하면 기기의 크기에 따라 유동적으로 적용되지 않기 때문이다.안드로이드에서는 픽셀 대신 dp를 사용한다. 이는 Density-Independent Pixel의 약자로, 밀도 독립형 픽셀이다.표준 단위인 dpi를 기반으로 하여 중밀도(mdpi, 160dpi)를 기준으로 논..

개발/트러블슈팅

[안드로이드] JdkImageTransform 실패로 인한 jlink 오류

안드로이드 스튜디오를 레이디버그 피쳐 드롭으로 업데이트한 이후에 갑자기 이런 오류가 발생했다.관련해서 국내 개발자들의 정보는 아예 없었고, 같은 증상이 발생한 외국인들의 토론 글이 있었지만 유용한 해결책은 찾을 수 없었다.다행히도 매번 invalidate cache하면 일시적으로 발생하지 않아서 그걸 반복하며 사이드 프로젝트를 개발하고 있었다. 그러다 이제는 이 비효율적인 프로세스를 먼저 해결하고 개발을 이어나가고자 여러 설정을 확인해봤는데,(1) compileSdk 버전도 변경하지 않았고(2) 현재 사용중인 버전의 AGP와 JDK의 조합은 문제 없이 잘 사용해오던 조합이였고(3) invalidate cache, build clean 등모든 방법을 다 해봤지만 일시적일 뿐, 완벽하게 해결되지 않았다. ..

개발/Kotlin

[Kotlin] 예외 처리 - 예상한 예상 밖의 결과

1.Throwable과 Exception, ErrorThrowable은 예외와 오류의 최상위 클래스이다.예외와 오류의 차이점은 복구 가능성으로, 예외에 대해서는 개발자가 적절한 처리를 통해 정상적인 실행을 유지할 수 있으나 오류는 그렇지 않다. 이 때문에 이 둘을 구분하여 개발자가 핸들링할 수 없는 오류에 대해서는 처리를 하지 않도록 설계되었다. 2. Kotlin에는 checked exception이 없다Java에서는 RuntimeException의 서브클래스가 아닌 Exception들을 checked exception이라 부르며, 이에 대한 처리를 컴파일러 수준에서 강제한다. 하지만 Kotlin은 Jvm 기반으로 설계되었음에도 checked exception을 지원하지 않는데, 그 이유가 뭘까?💡Ko..

개발/Android

[안드로이드] ART의 GC는 어떻게 동작할까(feat.Dalvik)

1. Dalvik과 ART안드로이드에서 사용하는 Dalvik과 ART(Android runtime)은 바이트 코드를 네이티브 코드로 변환하는 런타임이다.Dalvik의 JIT 컴파일 방식은 앱 실행 시마다 바이트코드를 해석하기 때문에 메모리 사용량이 높고 실행 속도가 느리다는 단점이 있고, GC도 모바일 환경에 최적화되어 있지 않아 구글은 이를 개선하기 위해 ART를 도입하게 된다.ART의 AOT 컴파일 방식은 설치 시에 미리 네이티브 코드로 변환하고 디스크에 저장한 후 실행 시에 저장된 네이티브 코드를 메모리에 로드해 실행함으로써 실행 속도를 개선하고, GC 메커니즘 또한 모바일 환경에 적합하도록 개선되었다. 2. Dalvik GC의 문제점Android 5.0 이전까지 사용된 Dalvik의 GC 메커니즘..

개발/Android

[안드로이드] 화면 회전과 ViewModel

0. 개요안드로이드 면접에서 나오는 단골 질문들 중 하나인 "화면 회전 시에 어떻게 되고, ViewModel을 사용하면 어떤 이점이 있나요?"를 많이 들어봤을 것이다.대부분의 기술 블로그에서는 "ViewModel이 Fragment/Activity와 독립적인 생명주기를 가져서 재생성 시에도 데이터를 유지할 수 있습니다"라고 설명하고 있다.오늘의 포스팅은 "과연 독립적인 생명주기 때문이라는 설명이 적절할까?"는 의문에서 출발한다. 1. ViewModel과 친구들(1) ViewModelStoreViewModel 인스턴스들을 저장하는 컨테이너이다. ViewModelProvider가 이를 활용하여 존재하는 ViewModel이 있으면 재사용하고, 없으면 새로 생성하여 저장한다. (2) ViewModelStoreOw..

개발/Kotlin

[이펙티브 코틀린] 프로퍼티는 동작이 아니라 상태를 나타내야 한다

Java를 사용하다 Kotlin으로 넘어오면서 많은 사람들은 Kotlin의 프로퍼티가 Java의 필드와 비슷하다고 느낀다.하지만 사실 이 둘은 전혀 다른 개념인데, 이펙티브 코틀린에서 이를 자세히 설명하고 있다. 1. 프로퍼티와 필드// Kotlin 프로퍼티var name: String = "왜?"// Java 필드String name = null; 프로퍼티와 필드 둘 모두 데이터를 저장한다는 공통점이 있지만, Kotlin의 프로퍼티는 더 많은 기능을 제공한다.가변 프로퍼티에는 자동으로 getter/setter를 가진다. 기본적 캡슐화가 되어있다.Java에서는 lombok 같은 라이브러리를 사용하여 어노테이션으로 지정해줘야 했던 것에 비교하면 사용자 편의성이 굉장히 높다. 또한 가변 프로퍼티는 사용자 정..

로키입니다
왜?