프로그래밍 404

[Compose] 빨간 점 시스템 만들기

UI에 작게 보이는 빨간 점은 유저에게 이것을 따라 가보라는 작은 넛지를 준다. 카카오톡에서도 내 친구들이 프로필을 업데이트했을때의 빨간 점을 못이기고 클릭했던 경험도 있을것이다.  빨간 점 시스템을 가장 잘 만들고 사용하고있는 쪽이 어딜까? 바로 게임이다!  게임덕후이자 개발자로서 평소에 게임을 하면서도 이건 어떻게 구현했을까, 상태관리 어떻게 하는걸까 감탄/고민을 자주한다. 요즘은 원신을 정말 재미있게 즐기고있는데, 원신은 유저가 빨간 점을 누르면 "원석"(게임 내 중요 재화)이 생긴다는걸 정말 잘 훈련시켜서 은근슬쩍 원신에서 일어나는 모든 이벤트들을 선전한다.  이런 빨간 점 시스템을 안드로이드에서 구현해보기위해, 내가 게임 개발자다...생각하고 자료를 찾아보았다.  유니티 에셋스토어에 올라온 Un..

Bruno > Postman Collection Import시 한글 깨짐 해결방법

Bruno는 API Testing Tool로, Postman의 대안 중 하나다. Postman은 유명하고 편리하지만 유료 서비스라 무료로 이용하면 한계가 있다보니 Bruno 또는 Hoppscotch를 선택하기도 하는데, Bruno는 Git으로 형상관리가 되다보니 무료인것 외에도 다른 장점도 존재한다. 하지만 사용하던 Postman Collection을 이전하려고 하면 Alphanumeric이 아니면 모두 -로 표시되어 당황하게된다... 몇개 안되면 그냥 참고 한글로 바꿀 수 있지만 import를 하는 이유는 귀찮아서니까! 이 문제를 해결하는 방법을 공유하려한다. 1. Clone BrunoBruno는 커뮤니티 버전이 오픈소스이기 때문에 https://github.com/usebruno/bruno Githu..

ManifestPlaceholder : 매니페스트에서 빌드 변수 사용하기

카카오 SDK 연동을 하다보면 AndroidManifest에 APP KEY를 요구하는데, 중요한 Api Key를 보관할때 properties 파일을 별도로 만들어두고 빌드시에 BuildConfig에 변수를 할당하여 사용하는 패턴이 일반적이다. 하지만 AndroidManifest에서 BuildConifg에 접근하는 방법은 없다. 이때 사용하는 것이 바로 ManifestPlaceholder다. 위 Manifest 내용은 카카오 SDK 예시인데, 저렇게 NATIVE_APP_KEY를 가져올 수 있도록 세팅해보자. 안드로이드 프로젝트를 만들면 기본적으로 생성되는 local.properties를 사용해보도록 하겠다. kakao.native_app_key 프로퍼티를 추가해준다....kakao.native_app_ke..

[KotlinConf2024] Kotlin 2.0의 새로운 피쳐들

1. Explicit Backing Fields (명시적 백킹 필드)명시적 백킹 필드가 어떤건지 이해하기 위해서 안드로이드 프로젝트에서 널리쓰이는 패턴의 코드를 살펴보자.class MyViewModel { private val _title = MutableStateFlow("Placeholder") val title: StateFlow get() = _title}title이라는 상태는 ViewModel에서만 수정할 수 있도록 이렇게 캡슐화 할 수 있는데, Kotlin 2.0에서는 훨씬 더 간결한 형태로 이를 표현할 수 있다.class MyViewModel { val title: StateFlow field = MutableStateFlow("Placeholder")}다가오는 ..

Android Room은 어떻게 Flow를 지원할 수 있었을까?

Room의 room-ktx 종속항목을 추가하면 Kotlin Extension과 Coroutine 지원을 받을 수 있게 된다. 이는 가져다쓰는 개발자 입장에서도 굉장히 편리해지는데, 그중에서도 Flow의 지원은 DB내의 데이터가 바뀔때마다 쿼리를 실행해서 결과값을 방출 할 수 있도록 해준다.implementation "androidx.room:room-ktx:$room_version" 데이터의 변화가 일어났을때 이를 감지해서 새로운 Flow를 방출하는 구조를 짜고싶었는데, 문득 Room이 생각나서 내부 구현을 찾아보게 되었다.@JvmStatic public fun createFlow( db: RoomDatabase, inTransaction: Boolean, tableName..

Mastering Android ViewModels: init {} 블록에서 상태를 초기화하는 것을 피하라

ViewModel의 init {} 블록에서 상태를 초기화하는 것은 편리해보인다.나도 프로젝트에서 종종 그렇게 해 오고는 했는데, 그렇게 하지말라는 이유는 다음과 같다. 1. ViewModel 생성과 강하게 커플링됨데이터를 가져오는 타이밍이 ViewModel 생성시에 있기 때문에, 새로고침 등 사용자 상호작용이나 기타 이벤트에 따라 데이터 로딩시점을 제어하기 어렵게 만든다.  2. 테스트하기 어려움ViewModel이 생성되자마자 데이터 로드가 시작되므로 1번의 이유로 인해 테스트하기 어려워진다.  3. 리소스 낭비의 가능성앱이나 화면에 진입하자마자 데이터를 필요로 하지 않을 경우, 자원의 비효율적인 사용으로 이어질 수 있음. 4. UI 응답성init {} 블록은 최대한 가볍게 유지해야한다. 여기에서 메인 ..

Mastring Android ViewModels: 필요하다면, 생성자에 의존성을 Lazy하게 주입하라

ViewModel의 생성자에 있는 모든 의존성들을 Lazy Inject하라는 것은 아니지만, 드물게 사용하는 것들은 Lazy로 바꿈으로서 초기화 성능을 개선할 수 있다. 의존성이 실제로 필요할때만 주입되므로 이로인한 이점은 다음과 같다. 1. 빠른 시작2. 더 낮은 메모리 점유율3. CPU 부하 감소 Lazy Initialization을 사용해야하는 경우- 규모가 큰 의존성- 드물게 사용되는 의존성- 조건부 의존성 케이스 스터디@HiltViewModelclass BookViewModel @Inject constructor( @IoDispatcher private val ioDispatcher: CoroutineDispatcher, private val bookmarkUseCase: dagger..

[Java] Timer의 Fixed-rate Execution의 함정

앱에서 정확한 시간마다 작업을 수행해야할때 Timer.scheduledAtFixedRate를 사용하던 중, 기이한 로그가 발견되었다. 바로 아주 짧은 시간에 여러번 호출되는 현상! 문서를 보면 메소드에 대한 대략적인 설명은 이렇다. scheduleAtFixedRate(TimerTask task, Date firstTime, long period)Schedules the specified task for repeated fixed-rate execution, beginning at the specified time.지정된 시간부터 고정된 간격으로 반복적으로 작업을 수행하도록 예약한다. 이 "Fixed-rate execution"에는 함정이있다.메소드를 눌러 문서를 더 자세히 살펴보면 다음과 같은 문단을 발..

의존성을 가지는 Initializer 만들기

Android Jetpack 라이브러리 중 하나인 App Startup은 안드로이드 앱 구동에 필요한 초기 설정들을 체계적으로 초기화하는데 유용한 라이브러리다. 아래는 App Startup의 사용 예시 코드인데, dependencies 함수를 보면 예시 코드의 로거 Initializer는 WorkManagerInitializer에 의존하고 있음을 알 수 있다.// Initializes ExampleLogger.class ExampleLoggerInitializer : Initializer { override fun create(context: Context): ExampleLogger { // WorkManager.getInstance() is non-null only after ..