목록분류 전체보기 (392)
Hanbit the Developer
문제 상황아래 화면에서 수집 진행도(NkAnimatedCircularProgress)와 물고기 그리드(LazyVerticalGrid)의 스크롤을 병합하고 싶었다.Column( modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally,) { NkAnimatedCircularProgress( progress = collectibles.calculateProgress(), description = stringResource(id = R.string.progress_rate) ) Spacer(modifier = Modifier.height(Dimens.Spacin..
배경 hashCode()는 주로 해시 기반의 컬렉션에서 객체를 저장하고 검색하는 데 사용됩니다. 오늘은 data class, Integer, Boolean, String에서 이 함수가 각각 어떻게 구현되었는지 알아보고자 합니다. hashCode() for data class data class User( val id: Int, val age: Int, val isStudent: Boolean, val firstName: String, val lastName: String, ) { init { hashCode() } } 위 코틀린 data class를 디컴파일 하면 아래와 같은 자바 코드가 생성됩니다. public int hashCode() { int var10000 = ((Integer.hashCode(..
배경 Java에서 List의 대표적인 구현체인 ArrayList와 LinkedList의 구현을 알아보겠습니다. ArrayList ArrayList는 MutableList의 기본 구현체이다. 코틀린에서 mutableListOf() 함수를 사용하면 ArrayList가 기본 구현체로서 반환됩니다. /** * Returns an empty new [MutableList]. * @sample samples.collections.Collections.Lists.emptyMutableList */ @SinceKotlin("1.1") @kotlin.internal.InlineOnly public inline fun mutableListOf(): MutableList = ArrayList() @SinceKotlin("1..
배경 개인적으로 Retrofit2의 구현을 분석한 적이 있는데 이때 suspend fun이 디컴파일될 때 마지막 인자로 Continuation이 붙으면서 처리된다는 것을 알게 되었고, 원리를 직접 알아보고 싶었습니다. 예시 1: 간단한 코루틴 다음과 같은 간단한 예시를 작성하였습니다. 기존 코드 class SampleViewModel : ViewModel() { fun logout() { viewModelScope.launch { val userId = getUserId() logoutUser(userId) } } private suspend fun getUserId(): Int = 0 private suspend fun logoutUser(userId: Int) { Log.d("SampleViewMod..
Usage Retrofit을 생성하는 데 자주 사용되는 가장 기본적인 코드입니다. Retrofit.Builder() .baseUrl(baseUrl) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build() Retrofit2.java Retrofit.Builder 빌더에는 다음과 같은 프로퍼티가 있습니다. public static final class Builder { private final Platform platform; private @Nullable okhttp3.Call.Factory callFactory; private @Nullable HttpUrl baseUrl; private final List c..
배경 지금껏 Retrofit2는 단순히 ‘OkHttp3를 쓰기 편하게 해주는 wrapping library’ 정도로 인지하고 있었습니다. 하지만 구현이 어떻게 되어 있는지 궁금하였고 특히 인터페이스에 어노테이션만 붙였을 뿐인데 이것이 어떻게 구현체가 되는지 궁금했습니다. 오늘은 Retrofit2가 어떻게 구현되어 있는지를 create() 함수에서 시작하여 top-down으로 알아보겠습니다. Usage 지금까지 Retrofit2를 어떻게 사용했는지를 돌이켜보겠습니다. 먼저 인터페이스로 API가 어떻게 호출되어야 하는지를 정의해주곤 하였습니다. interface PhotoService { @GET("api/v1/albums/{id}/photos") suspend fun readPhotoList( @Heade..
Overview 예시 코드 SwipeToAction( swipeActions = SwipeActions.withSameActions( action = SwipeAction.deleteAction { /* TODO: onClickDeleteActionButton */ } ) ) { modifier -> Row( modifier = modifier // YOU MUST ADD IT! .fillMaxWidth() .background(Color.White, RoundedCornerShape(8.dp)) .padding(8.dp), ) { Text(text = "Sample") } } 위처럼 swipeActions를 지정해준 뒤 내부 컨텐츠에 modifier를 지정해주면 곧바로 swipe-to-action이 적..
배경 구현을 하다보면 Room이나 DataStore에서의 Flow를 stateIn 함수를 통해 StateFlow로 변환하여 사용하는 경우가 잦다. public fun Flow.stateIn( scope: CoroutineScope, started: SharingStarted, initialValue: T ) scope, initialValue는 어떤 것인지 명확하게 알 수 있으나 started는 아니다. started 인자의 타입인 SharingStarted에 대해서 알아보고자 한다. Eagerly SharingStarted에는 3가지 companion object가 있다.(Eagerly, Lazily, WhileSubscribed) 첫번째는 Eagerly이다. Sharing is started imme..
배경 Flow는 구독(collect 등) 시작 시점에 동작을 시작하는 cold stream이고, StateFlow는 구독자의 구독 시점과 상관없이 동작을 시작할 수 있는 hot stream이다. 이 주제에 대해 말로만 인지하고 있었어서 코드로 확인해보고 싶었다. 동작 확인 Flow class FlowViewModel : ViewModel() { val tmp: Flow = flow { val nums = listOf(1,2,3,4,5,6,7,8,9,10) nums.forEach { delay(1000) emit(it) } } fun onClick() { viewModelScope.launch { tmp.collect { Log.e("tmp", it.toString()) } } } } 위 코드를 실행하고 ..
문제 상황앱에서 계정을 생성했을 때 그 계정에 종속되는 TutorialTask 리스트를 초기화해야 한다. AddUserUseCase 클래스에서 InitializeTutorialTasksUseCase를 호출하고자 한다:class AddUserUseCase @Inject constructor( private val userRepository: UserRepository, private val appStateRepository: AppStateRepository, private val initializeTutorialTasksUseCase: InitializeTutorialTasksUseCase,) { suspend operator fun invoke(user: User) { ..