Android Migrate an xml view to compose

이미지
사용 버전: Android Studio Koala 2024.1.1 사용 언어: Kotlin 2.0.10 안드로이드 Migrate an xml view to compose를 알아보겠습니다. 오늘은 XML(엑스엠엘) View(뷰)로 만들어진 앱을 Compose(컴포즈)로 변경해 보는 작업을 해봅시다. 아쉽지만 Compose에 대한 설명은 없습니다. 이미 알고 계신다고 생각하고 진행할 거예요. 아래는 현재 XML로 작성된 제 앱입니다. 이걸 Compose로 변경할 것입니다. 재미있어 보이지 않나요? Compose로 변경할 때에는 보통 Fragment 단위로 변경하는 것을 추천합니다. 다시 말하자면, 화면 단위로 변경하는 것이죠. buildFeatures에 compose = true를 적어줍니다. dependencies에는 다음의 내용을 추가해 줍니다. 설명을 위해 version catalog는 적용하지 않았습니다. implementation(platform("androidx.compose:compose-bom:2024.08.00")) implementation("androidx.compose.material3:material3") implementation("androidx.compose.ui:ui-tooling-preview") debugImplementation("androidx.compose.ui:ui-tooling") Sync Now를 눌러줍니다. plugin에 compose compiler를 추가해 줍니다. Project 용 build.gradle id("org.jetbrains.kotlin.plugin.compose") version("2.0.10") apply false Sync Now를 눌러줍니다. compose를 적용할 모듈 용 build.gradle id("org.jetbrains.kotlin.plugin.compose") ...

Android Kotlin CoroutineScope and CoroutineContext

사용 버전: Android Studio Koala 2024.1.1 사용 언어: Kotlin 2.0.10 안드로이드 코틀린 CoroutineScope and CoroutineContext를 알아보겠습니다. Coroutine(코루틴)에는 중요한 요소가 세 가지 정도 있습니다. CoroutineScope(코루틴 스코프), Job(잡), CoroutineContext(코루틴 컨텍스트)입니다. CoroutineScope는 모든 코루틴에 필요한 요소입니다. https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-scope/ CoroutineScope로 생명 주기를 관리할 수 있습니다. 보통 class의 생성 시, scope를 만들고, class의 소멸 시, scope를 취소합니다. scope가 취소되면 scope에 있는 모든 coroutine은 정지됩니다. CoroutineScope에는 기본적으로 CoroutineContext 4가지 요소가 들어갑니다.  Job, CoroutineDispatcher(코루틴 디스패처), CoroutineName(코루틴 이름) 그리고 CoroutineExceptionHandler(코루틴 익셉션 핸들러). 이러한 4가지 중 Job과 CoroutineDispatcher가 가장 많이 사용되는 CoroutineContext입니다. 미리 정의된 Scope들이 있습니다. GlobalScope, MainScope, supervisorScope, coroutineScope가 있으며, 안드로이드에서는 생명주기에 맞춰진 lifecycleScope, viewModelScope가 있으며, 테스트를 위한 TestScope도 존재합니다. Job부터 보겠습니다. https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/ Corou...

RFC 9421

이미지
오늘은 RFC 9421에 대해 알아보겠습니다. https://datatracker.ietf.org/doc/html/rfc9421 1. 기술이 생겨난 이유 보통 TLS를 많이 사용합니다. TLS는 하나의 연결만 보증하지 중계기 간의 연결은 보증할 수 없습니다. 또한, Application은 검증을 위해 TLS 인증서와 독립적인 key가 필요하기도 합니다. 그리고, 전체적인 message를 모르더라도 message를 보호할 수 있어야 합니다. JSON Web Signature의 경우 매번 중복된 payload가 필요하게 됩니다. HTTP message만을 위한 무결성과 검증 기술을 만들게 되었습니다. 2. 구성 목록   •  Signature base   •  Signature-Input   •  Signature   •  Accept-Signature 3. Signature base 중계기에서 HTTP 변형이 가능하기 때문에 bit 단위를 비교할 순 없습니다. 대신, 의미가 같은지를 확인합니다. 여기에 사용되는 것이 Signature base입니다. 아래는 signature base를 만드는 표현식입니다. 예시를 보시죠. 위의 HTTP Header는 아래의 Signature base로 표현될 수 있습니다. (Signature-Input을 바탕으로 생성) Component Identifier는 아래와 같습니다. •  Derived Component @method @target-url @authority @scheme @request-target @path @query @query-param @status •  Field-content accept 등 @signature-params Signature base 제일 마지막에 추가되며, 생성, 검증을 위한 metadata를 포함합니다. 서명되는 모든 항목과 추가적인 signature parameters로 구성됩니다. •  ...

Android Kotlin Queue refactoring

이미지
사용 버전: Android Studio Koala 2024.1.1 안드로이드 코틀린 Queue refactoring을 알아보겠습니다. Queue(큐)는 기본적인 자료구조에 많이 등장하는 것으로 들어간 순서대로 나옵니다. 보통 배열로 사용하는 List보다 빠릅니다. 4년 전에 작성한 코드입니다. 나름 생각해서 만든 코드인데요. 광고가 4번째 칸마다 들어가도록 만든 로직입니다. 현재 보니 충분히 Queue로 로직을 변경할 수 있을 것 같아 보이네요. 원래 item(아이템)들을 하나의 큐에 넣고 광고를 또 다른 큐에 넣어줍니다. 두 개의 큐 중에 하나라도 다 떨어질 때까지 진행하면서 4번째 차례마다 광고를 꺼내서 넣어줍니다. 무한 반복이 끝난 후, 만약 남은 원래 item이 있다면 차례로 넣어줍니다. Kotlin에 있는 ArrayDeque(어레이 덱)를 사용해봅시다. Double Ended Queue의 준말입니다. https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-array-deque/ 다음과 같이 refactoring(리펙토링) 되었습니다. 끝. 카테고리: Android

Android Unit tests with an android dependency

사용 버전: Android Studio Koala 2024.1.1 안드로이드 Unit tests with an android dependency를 알아보겠습니다. Unit(유닛) test(테스트) 또는 Local(로컬) test는 JVM에서 실행됩니다. 즉, Android와 관련된 패키지가 있다면 정상적으로 작동하지 않는다는 얘기입니다. 제 앱에 Unit test를 추가하다가 발견한 문제입니다. Domain(도메인)에 있는 Usecase(유즈케이스)가 test에 사용되었습니다. import android.net.InetAddresses import android.os.Build IP(아이피) 주소를 확인하기 위한 InetAddresses와 OS(운영체제)의 SDK(개발자 도구) 버전을 확인하기 위한 Build.VERSION.SDK_INT를 사용하였습니다. 보시다시피 android에 dependency(의존성)를 가집니다. 이러한 것을 해결하는 방법으로는 Mockito(모키토)를 사용하거나 android 의존성을 없애거나, Instrumented(계측) test에서 test를 진행하는 것입니다. 저는 InetAddresses를 Guava 라이브러리로 대체하며 os.Build도 같이 제거하였습니다. 이렇게 제거하니 test가 정상적으로 작동되더군요. import com.google.common.net.InetAddresses 끝. 카테고리: Android

Android Jetpack Navigation with multi-module

이미지
사용 버전: Android Studio Koala 2024.1.1 안드로이드 Jetpack Navigation with multi-module을 알아보겠습니다. 현재 하나의 module(모듈)로 구성된 제 앱을 multi-module(멀티 모듈)로 변경하고 있습니다. 그러다 만난 난관이 있는데요. 바로 Jetpack(잿팩) Navigation(내비게이션)입니다. Navigation은 Fragment 간의 화면을 전환하는 데 도움을 주는 라이브러리입니다. 문제는 여기서 발생합니다. 제 앱이 이런 식으로 Modularization(모듈화)을 진행합니다. :app -> :feature -> :ui :app에 navigation.xml 파일을 두게 되면, :feature에서 :app을 보지 못해 navigate를 사용할 수 없게 됩니다. 반대로 이것을 :ui에 두게 되면, :ui는 :feature(피처)를 참조할 수 없어서 navigation.xml에 fragment(프레그먼트)를 참조할 수 없게 됩니다. 어떻게 해야 할까요? 저는 이렇게 해결했습니다. Navigation Graph(그래프)를 Kotlin DSL로 전환합니다. https://developer.android.com/guide/navigation/design/kotlin-dsl 그리고, navigation library는 Kotlin DSL에서 Type Safe Args를 사용할 수 있는 2.8.0-alpha08 이상으로 해줬습니다. https://developer.android.com/jetpack/androidx/releases/navigation#2.8.0-alpha08 Navigation graph를 다음과 같이 설정해 줍니다. 이것을 MainActivity에서 호출해 줍니다. Serializable은 :Model 모듈에 만들었습니다. 이러한 navigation.xml은 kotlin DSL로 변환하면, 이렇게 됩니다. 전체적인 구조는 :app, :features -> :model ...

Android BuildConfig

이미지
사용 버전: Android Studio Koala 2024.1.1 안드로이드 BuildConfig를 알아보겠습니다. BuildConfig(빌드 컨피그)는 Build(빌드) 시에 자동으로 정보를 생성하여 Runtime(런타임)에 참조할 수 있도록 만들어주는 기능입니다. 참고 문서: https://developer.android.com/build/gradle-tips 현재 제 앱에서는 MainActiivty의 companion object에 Debug를 설정하는 코드를 사용하고 있습니다. 직접 Debug 모드를 설정할 수 있다는 점이 좋았는데요. 문제는 앱 구조를 Official android architecture(공식 안드로이드 아키텍처)로 변경하면서 MainActivity 의존성을 제거해야 하는 것이었습니다. 의존성 분리도 하고, DEBUG(디버그)를 확인할 때 좋은 것이 바로 BuildConfig 기능입니다. 사용할 module(모듈)의 gradle(그레이들)에 갑니다. buildFeatures 안에 buildConfig = true를 적어줍니다. Sync Now 및 Build를 해줍니다. 그 뒤 사용은 이렇게 합니다. 참고로 Build type에 따라서 새로운 buildConfigField를 만들 수도 있습니다. 아래는 IS_DEBUG라는 Field(필드)를 새로 만들어 봤습니다. BuildConfig 생성 위치는 module 이름 - build - generated - source - buildConfig - flavor 이름 - 패키지 이름 - BuildConfig.java입니다. BuildConfig.java를 보시면 이렇게 잘 들어간 모습을 볼 수 있습니다. 끝. 카테고리: Android

Android Project dependency management

이미지
사용 버전: Android Studio Koala 2024.1.1 안드로이드 Project dependency management를 알아보겠습니다. Android 프로젝트에 우리는 여러 dependency(의존성)를 사용합니다. 그런데, 우리가 사용 중인 라이브러리에 새로운 버전이 출시된 것을 알아채고 관리하려면 어떻게 해야 할까요? 이번 시간에는 라이브러리를 최신으로 유지하는 데에 도움을 주는 자동화 도구를 알아보겠습니다. 찾아보니 두 가지 정도가 나옵니다. 1. Dependabot https://github.com/dependabot 2. Renovate Bot https://github.com/renovatebot 이번 시간에는 Github에서 만든 Dependabot만 다뤄보겠습니다. 본인 Github 프로젝트의 Settings로 들어갑니다. 옆의 항목에 Securite - Code security and analysis로 갑니다. Dependabot 항목이 주룩 나옵니다. 간단한 Dependabot version updates를 Enable 해봅시다. 미리 작성된 항목이 나옵니다. 기본적으로 YAML 형식이 사용됩니다. github-action과 gradle을 업데이트하는 것으로 설정했습니다. 업데이트 확인 주기는 주 단위인 weekly로 설정해 줬습니다. Dependabot이 자동으로 PR을 생성합니다. 참고 프로젝트: https://github.com/Jaehwa-Noh/Project-Flight-Search-App 끝. 카테고리: Android

Android Compose Instrumentation test to unit test

이미지
사용 버전: Android Studio Jellyfish 2023.3.1 안드로이드 컴포즈 Instrumentation test to unit test를 알아보겠습니다. Instrumentation(계측) test(테스트)라고 하면, 보통 UI(유아이) test를 말합니다. Unit(유닛) test는 보통 코드의 로직을 test 할 때 사용합니다. Instrumentation test의 단점은 emulator(에뮬레이터)나 실제 device(장치)가 있어야 한다는 점인데요. 이는 테스트의 속도를 떨어뜨리게 됩니다. 이러한 Instrumentation test를 emulator 없이 실행할 수 있게 해주는 것이 있습니다. 바로 Robolectric(로보레트릭)입니다. https://robolectric.org 이처럼 Unit test처럼 test 할 수 있게 해줍니다. 적용해 봅시다. 앱 용 Build.gradle로 갑니다. testOptions를 적어주고, unitTests 그리고 isIncludeAndroidResources를 true로 만들어 줍니다. libs.versions.toml robolectric을 정의합니다. 그리고 testImplementation을 적어줍니다. 여러분 프로젝트에 libs.versions.toml을 사용하지 않는다면, 예시처럼 org.robolectric:robolectric:4.12를 적어주시면 됩니다. 자, 그러면 이제 context가 필요해서 androdTest로 만들었던 것들을 그냥 test로 옮길 수 있게 됩니다. 옮길 대상은 database와 repository입니다. unitTest로 옮겨졌네요. 그다음 해야 할 것을 문서에서 보면, 아래처럼 RunWith를 추가해 주는 것입니다. RunWith(RobolectricTestRunner.class) 옮겨온 test class 위에 적어줍니다. 그리고 기존에 context를 가져오는 코드를 변경합니다. RuntimeEnvironment.getApplication().ap...