Android

Android/번역

[번역] Crash Course on the Android UI Layer Part 1

Crash Course on the Android UI Layer (안드로이드 UI Layer 에 대한 단기 속성 과정정도로 볼 수 있을 것 같아요) (전 Google Android DevRel 로 믿고 보는 아티클이에요. 다만 저의 번역 실력을 믿으시면 안됩니다. 중간중간 주관적인 생각도 들어갈 예정이에요.) 해당 블로그의 글은 https://developer.android.com/topic/architecture/ui-layer 에 대한 정리하는 글 입니다. 우리는 UI Layer 와 관련된 많은 Entity 들을 살펴보고, 각각의 부분에 대해 이해하고, 모범 사례에 대해 이야기해볼 예정이에요. 해당 시리즈의 마지막에서는 우리는 UI layer 에서 발생하는 일반적인 것들과, UI Layer 안에서 ..

Android/Compose

Tips. Compose stable, unstable 상태와 자주 사용하는 어노테이션 정리

혹시나 잘못된 내용이 있다면 정정해주세요 (항상 헷갈리더라구요) Stable vs Unstable 상태 Stable : Recomposition 일 발생했을 때 parameter 가 Stable 하다면 Compose Runtime 에서 Recomposition 을 건너뛰는 것(Skippable)이 가능한 상태를 말해요 Unstable : 상위 Composable 함수에서 Composition, Recomposition 이 발생했을 때, 항상 Recomposition 이 발생하는 상태를 말해요 Stable 어노테이션 vs Immtable 어노테이션 를 알아보기 전에, 내부/외부로부터 상태 변경 에 대한 부분을 꼭 알아야해요 fun ContactRow(contact: Contact) { var selecte..

Android/Development Tips

간단 Tips. Retrofit2 을 사용할 때 언제 WorkerThread 에서 동작할까 ?

Retrofit2 사용할 때 혹은 코루틴과 함께 사용할 때 기본으로 WorkerThread 에서 동작한다는 이야기 들어보신적 있으시나요? 항상 WorkerThread 에서 동작한다고 기대하면 안되는 케이스와 기대해도 되는 케이스에 대해 알아보려해요~! 대략 Retrofit2 의 기본 처리, 코루틴의 기본처리, jakewharton 이 제공하는 CoroutineCallAdapterFactory 처리, RxJava 의 기본처리 방식에 대해 알아볼꺼에요. Retrofit2 로 요청을 보내는 로직에 Thread.currentThread().name 을 출력해보면, "OkHttp ${RequstUrl}" 형식으로 출력되고 있을꺼에요. 이는 OkHttp 에서 가지고 있는 WorkerThread 로 동작하고 있다고 ..

Android/Development Tips

Compose. StateFlow + List 를 활용하여 Recomposition 할 때 Tips

오픈 카톡방에서 질문이 올라와서 공유를 위해 작성해둡니다. List(MutableList)를 사용할 때, 갯수가 동일하고 특정 요소의 프로퍼티만 변경하는 경우 StateFlow 의 setValue 까지는 동작하지만, Recomposition 이 발생하지 않아 화면이 업데이트 되지 않는 경우가 존재 합니다. 이는 기본적으로 Kotlin의 List를 Compose 컴파일러는 불안정한 자료구조로 보기 때문에, 사이즈가 동일하고, 한 프로퍼티만 변경된 경우라면, 리스트 자체는 바뀌지 않은 것으로 간주되어 Compose가 이를 감지하지 못할 수 있습니다 그래서 따로 핸들링 해줘야 합니다. (Stable 과 흡사합니다.) 그런 경우 검색해보면, https://velog.io/@jsoh/Jetpack-Compose-..

Android/Development Tips

Summary MVI 직접 작성 해야/하지 않아야 하는 이유

https://www.youtube.com/watch?v=E6obYmkkdko 를 정리만 해둔 글 입니다. 주요 컨셉 단방향 데이터 흐름 (unidirectional cycle of data) 논블록킹(non blocking) 불변상태(immutable state) 모델(Model)에서 유저(User)의 인텐트(Intent =의도)를 처리하는 시간이 오래걸릴 수 있기 때문에, 데이터 사이클(cycle of data) 을 논블럭(non-blocking) 하는 것이 매우 중요 합니다 상태(state)의 무결성을 보장하는 것이 모델이 하는 일 외부에 의해 상태가 변화 되지 않습니다(immtable) 내부에서는 상태가 변화합니다 인텐트는 네트워크 작업과 같은 비즈니스 작업을 수행하는 변환기(transformer..

Android/Development Tips

확대, 축소, 이동, 회전 가능한 컴포즈 뷰

예시 영상은 티스토리 버그로 동영상 첨부가 안되어, 파일로 첨부합니다. @Composable fun ZoomableBox( modifier: Modifier = Modifier, enableRotation: Boolean = false, minScale: Float = 0.5f, maxScale: Float = 3f, content: @Composable ZoomableBoxScope.() -> Unit ) { var rotationZ by remember { mutableStateOf(0f) } var scale by remember { mutableStateOf(1f) } var offsetX by remember { mutableStateOf(0f) } var offsetY by remember {..

Android/Development Tips

간단 Tips. FrameLayout 위에 Fragment 를 올리는 것보다 FragmentContainerView 에 Fragment 를 올리는 것이 안전한 이유

FrameLayout 위에 Fragment 를 올려둔다면 Fragment 를 잘못 사용하거나, 구성요소 변경(Configuration change) 로 복원되는 경우 아래와 같은 에러를 만날 수 있습니다. 에러는 간단 합니다 상태를 저장하는 onSaveInstanceState 콜백 이후에 Commit 하려 했으니 상태를 저장할 수 있는 단계가 넘어간 상태이기에 불가능 한 상태라는 의미 입니다. 결국 FrameLayout 위에 Fragment 를 올려두게 되면, 상태에 대해 잘 다뤄줘야 합니다. 상태 저장 상관 없이 사용하고 싶다면 commit 이 아닌, commitAllowingStateLoss 메서드를 명시적으로 호출해줘야 합니다. 기본적으로 FragmentContainerView 는 FrameLayo..

Android/Development Tips

간단 Tips. Lottie 에서 Url 을 통해 로드할 때, Unable to parse composition 에러가 발생한다면 ?

결론만 이야기 드리면 LottieAnimationView 클래스에서 제공하는 setFailureListener 를 구현하면 됩니다. Url 을 통해 Lottie 를 이용할 경우, setAnimationFromUrl 를 사용하게 되는데 코드를 차근차근 보면 CacheComposition (캐시 허용) 이 true 라면 앞의 메서드가 호출되어 cacheKey 에 "url_" prefix 가 붙은 cacheKey 가 넘어가고 아니라면 cacheKey 에는 null 이 들어가게 되고 결과를 LottieTast 자료형의 task 에 담고 있습니다. 그리고 실패하는 경우에는 wrappedFailureListener 콜백 함수를 통해 결과를 넘겨 주고 있습니다. 실패했을 때 보여줄 이미지(fallbackResourc..

Android/Development Tips

간단 Tips. 코루틴 SupervisorJob 또는 SupervisorScope 를 사용해야 하는 경우

아래의 함수는 OneShot 으로 어떤 데이터를 가져올 때 많이 구현하게 되는 코드모양새 입니다. 그리고 aUseCase 에서 어떤 에러가 발생하면 runCatching 에 Catch 되어 최종적으로 onFailure 메서드가 호출 됩니다. fun fetchData() { viewModelScope.launch { runCatching { withContext(Dispatchers.XX) { aUseCase() } }.onSuccess { aResult -> }.onFailure { } } } 하지만 이따금식 여러개의 데이터를 가져와야하는 경우가 있습니다. fun fetchData() { viewModelScope.launch { runCatching { listOf(async { aUseCase() }..

Nanamare
'Android' 카테고리의 글 목록 (2 Page)