목록Android (57)
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..
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이 적..
문제 상황앱에서 계정을 생성했을 때 그 계정에 종속되는 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) { ..
문제 상황 로딩 화면에서 Success.NotEmpty 상태가 되어야 하는데, 중간에 Success.Empty 화면이 아주 짧게 보이는 문제가 발생하였다. 기존 코드 @HiltViewModel class TodoViewModel @Inject constructor( // ... ) : ViewModel() { private val _uiState: MutableStateFlow = MutableStateFlow(TodoUiState.Loading) val uiState = _uiState.asStateFlow() private val activeUserId: StateFlow = getActiveUserIdUseCase() .stateIn(viewModelScope, SharingStarted.While..
안드로이드 애플리케이션은 리눅스 프로세스에서 실행되며, 애플리케이션 코드 일부가 실행되어야 할 때 프로세스가 생성된다. 다른 애플리케이션이 메모리를 필요로 하면서 기존 애플리케이션이 더이상 쓰이지 않으면 종료될 수 있다. 안드로이드의 특이하면서 기본적인 특징은 애플리케이션 프로세스의 라이프타임이 해당 애플리케이션에 의해 결정되지 않고, 시스템에 의해 제어된다는 점이다. 시스템은, 실행 중인 애플리케이션 요소, 사용자에게 얼마나 중요한지, 시스템에서 사용 가능한 전체 메모리의 양을 고려한다. 개발자는 Activity, Service, BroadcastReceiver 같은 컴포넌트들이 애플리케이션 프로세스의 수명에 영향을 어떻게 미치는지를 알아야 한다. 컴포넌트를 올바르게 사용하지 않으면 시스템이 앱을 강제..
The different app startup states 앱을 처음부터 시작하는 cold start를 기준으로 최적화하는 것이 권장된다. 최적화 지표를 위한 지표는 다음과 같다: TTID: time to initial display TTFD: time to fully drawn Cold start 앱이 처음부터 시작하는 것을 의미한다. 기기 부팅된 뒤 앱이 처음으로 시작될 때, 앱이 시스템으로부터 종료된 후 앱이 시작될 때 콜드 스타트가 발생한다. 소요 시간이 가장 긴 유형이다. 콜드 스타트 초기에 시스템은 다음과 같은 작업을 수행한다: 앱 로드 및 시작 앱 시작 후 곧바로 blank starting window 띄움 앱 프로세스 생성 앱 프로세스가 생성되면 프로세스는 다음과 같은 작업을 수행한다: a..
배경Room에 새 테이블로 User를 추가하였더니 아래와 같은 에러가 발생하였다.error: There is a problem with the query: [SQLITE_ERROR] SQL error or missing database (no such table: user)GPT에 의하면 이 경우 DB 버전을 올린 뒤 database에 migration strategy를 제공하라고 하였다:1. Update Database Version@Database(entities = [TaskEntity::class], version = 2)abstract class NnDatabase : RoomDatabase() { abstract fun taskDao(): TaskDao abstract fun use..
ViewModel 생성 방법 ViewModelStore, ViewModelProvider에 대해 알아보기 전에, ViewModel을 어떻게 생성할 수 있는지부터 파악하여 top-down으로 알아보고자 한다. ViewModelProvider를 통한 생성 ViewModelProvider라는 클래스를 생성하고 get 함수를 통해 뷰모델을 얻을 수 있다. 이때 ViewModelProvider.Factory라고 하는, 뷰모델 생성 방식을 정의한 인터페이스를 따로 넣어줄 수도 있다. 지정하지 않으면 디폴트 팩토리를 사용하게 된다. class MyActivity : AppCompatActivity() { private lateinit var myViewModel: MyViewModel override fun onCr..