벌써 우아한테크코스 레벨 4! 배우면 배울수록 배워야 할 것도 많아지고 기억해야 할 것도 많아지는 기분이다. 레벨 3에선 팀 프로젝트 진행을 위해 미션이 사라졌었다. 레벨 4엔 "심화 미션" 이라는 이름으로 다시 미션이 돌아왔고 더 깊은 공부를 할 수 있게 되었다. 그 첫 번째는 “자동 DI 구현하기” Dagger Hilt 나 Koin 을 제대로 사용해본 적 없이 수동 DI 만 구현해본 나에게 자동 DI 가 무슨 말인지 이해조차 되지 않았다. 그래서 처음엔 수동 DI 부터 만들어 보았다. private val viewModelFactory = object : ViewModelProvider.Factory { override fun create(modelClass: Class): T { return whe..
분류 전체보기
Festago 를 개발하면서 ViewModel 의 UiState 및 Event 를 감지하기 위해 LiveData 를 사용했다. 이상적으로 ViewModel 은 Android 를 알아선 안된다. 테스트 가능성, 메모리 누수 안전성, 모듈성을 향상시킨다. 참고: AndroidDevelopers 블로그 https://medium.com/androiddevelopers/viewmodels-and-livedata-patterns-antipatterns-21efaef74a54 이를 이유로 안드로이드 의존성을 갖는 LiveData 를 사용하던 기존 코드들을 Kotlin 의존성을 갖는 Flow 로 Migration 해보기로 했다. StateFlow 와 SharedFlow 에 대한 이론적인 글은 다음 글을 참고해주세요...
자동 DI 블로그 글을 쓰다가 리플렉션에 대한 정리를 먼저 하고 넘어가는게 좋다고 판단되어 주제로 선정하였다. 자동 DI 를 구현하려면 리플렉션을 먼저 알아야한다. Reflection 이 뭐지? kotlin in Action 에 따르면 실행 시점에 동적으로 객체의 프로퍼티와 메서드에 접근할 수 있게 해주는 방법이다. 이는 성능을 떨어뜨리며 객체지향을 무시해버리기 때문에 개발할 때 보통 사용하지 않는 방법이다. (아래 사용 방법을 보면 이해할 것이다.) 하지만 라이브러리 등을 구현하려면 꼭 필요한 경우도 존재한다. 코틀린에서는 두 가지 서로 다른 Reflection API 를 사용할 수 있는데 자바 Reflection, 코틀린 Reflection 이 있다. 코틀린 클래스는 자바 바이트코드로 컴파일 되기 때..
안드로이드 테스트 피라미드 피라미드를 올라갈수록 비용 증가, 아래로 내려갈수록 더 많은 테스트가 작성되어야 한다. 안드로이드 테스트를 작성해 봤거나 그렇지 않더라도 두 가지 패키지를 보았을 것이다. androidtest : 실제 또는 가상 디바이스에서 실행할 테스트를 작성한다. JVM 만으로는 검증할 수 없는 테스트가 포함된다. test : 로컬 JVM에서 실행되는 테스트이다. 단위 테스트를 작성한다. 안드로이드 의존성이 있는 테스트는 모두 androidTest 하위에 위치해야 하는걸까? UI 로직을 검증하기 위한 테스트를 단위 테스트로 만들 수는 없을까? Robolectric Robolectric을 사용하면 JVM 내에서 "시뮬레이션된" 안드로이드 환경에서 테스트가 실행된다. 즉, 한마디로 안드로이드 ..
StateFlow & SharedFlow StateFlow 와 SharedFlow 는 다수의 소비자에게 상태 및 값을 방출하는게 가능하도록 최적화된 Flow 이다. Flow 와 StateFlow & SharedFlow 에 cold flow, hot flow 라는 얘기가 자주 나오는데 무슨 뜻일까? Cold & Hot Flow 그냥 Flow 는 cold Flow 이다. 소비자가 활성화되어 있지 않으면 방출도 중지된다. 소비자와 생산자가 1 대 1 관계이다. StateFlow 와 SharedFlow 는 Hot Flow 이다. 소비자랑 상관 없이 참조가 존재하는 한 메모리에 남아서 방출한다. 다수의 소비자가 가능하다. StateFlow state-holder 로 observable flow 이다. 현재 상태 ..
우아한테크코스에서 flow 를 배우지 않는다는 소식에 혼자 독학하는 flow deep dive! 시작! https://developer.android.com/kotlin/flow Android의 Kotlin 흐름 | Android Developers Android의 Kotlin 흐름 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 코루틴에서 흐름은 단일 값만 반환하는 정지 함수와 달리 여러 값을 순차적으로 내보낼 developer.android.com Flow 란? Coroutine flow 는 단일 값만 반환하는 suspend function 과 다르게 여러 값을 순차적으로 내보낼 수 있는 type 이다. 예를 들어 이 flow 를 사용하면 데이터베이스의 업데이트를 실시간..
책 요약 및 리뷰 리뷰는 개인적인 생각 및 의견으로 파란색으로 남기겠습니다. 들어가기 전에 코드 작성의 목적은 문제 해결이다. 우리는 보통 상위 수준의 문제를 하위 수준의 문제들로 나누어 해결한다. 하위 수준의 문제를 해결하는 방법도 중요하지만 그 코드를 어떻게 구성하는가도 중요하다. 코드를 구성하는 방법은 코드 품질의 기본적인 측면 중 하나이다. 코드를 잘 구성한다는 것은 간결한 추상화 계층을 만드는 것으로 귀결된다. 문제를 추상화 계층으로 나누고 어떻게 코드를 구성하는지, 그 효과로 가독성, 모듈성, 재사용성, 일반화성, 테스트 용이성이 개선되는지 확인해보자. -> 이 책에서는 계속해서 가독성, 모듈성, 재사용성, 일반화성, 테스트 용이성을 강조하고 있다. 좋은 코드를 만들기 위해서는 개발자가 유념해..
현재 프로젝트에 적용 중인 로깅 방식을 공유하려고 한다! 로깅 전략 의 필요성 로깅 전략은 어떤 로그를 어떤 방식으로 남길지, 로그를 얼마나 관리할 지 등이다. 그럼 애플리케이션에 어떤 로깅 전략이 필요할까? 아래는 가장 중요하다고 생각하는 두 가지 이다. 1. Error 로깅 네트워크 통신하는 부분에서 왜 Failure 하는지, Exception 이 어디서 어떻게 발생하는지 Message 는 무엇인지 로깅하고 싶을 수 있다. 오류가 반복된다면 fix 가 필요할 것이다. 2. 비즈니스와 연결 사용자가 어떤 flow 로 앱을 이용하는지 어떤 화면에 오래 체류하는지 체크해서 비즈니스와 연결 지어 이용할 수 있다. 로깅의 범위나 방향은 앱마다 다르다. 즉, 어떤 로깅 전략을 세울 지 앱 바 앱 이고 팀 바 팀..
다시 돌아온 코루틴! 그럼 바로 문제부터 시작해볼까요? 문제1 다음 코드는 언제 끝날까요? fun main() = runBlocking { val job = launch { while (true) { println("While in ${Thread.currentThread().name}") } } } 정답 이 코드는 안끝납니다! launch 스코프로 실행하고 runBlocking 이 끝날 때 까지 기다리기 때문에 무한루프를 타게 됩니다. 문제 2 그럼 이 녀석은 언제 끝날까요? fun main() = runBlocking { val job = launch { while (true) { println("While in ${Thread.currentThread().name}") } } println("종료"..
이전에 Presenter 테스트 작성으로 테스트의 중요성을 알아봤다. https://seonghoonc.tistory.com/20 Presenter 테스트 작성하기 (안드로이드 MVP) : [우아한테크코스 5기 AN_베르] 들어가기 전에 이 글은 MVP 패턴 적용이나 단위 테스트에 대한 경험이 없다면 이해하는데 어려움이 있을 수 있습니다. 테스트가 필요한가? 장바구니 주문 미션 2단계 제출할 때까지 Presenter 테스 seonghoonc.tistory.com 또한 MVP 를 MVVM으로 리팩터링하는 과정도 거쳤다. https://seonghoonc.tistory.com/21 [안드로이드] MVP 패턴 MVVM 패턴으로 리팩터링하기 MVP 패턴으로 작성한 단순한 화면을 MVVM 패턴으로 바꿔보자! + ..