0Pricing
Android Academy · 강의

오류 처리와 사용자 경험

봉인 클래스로 UI 상태(Loading/Success/Error)를 모델링합니다. ProgressBar와 재시도 작업이 있는 Snackbar를 표시하고 TextInputLayout에서 인라인 유효성 검사 오류를 보여 줍니다.

오류 처리와 사용자 경험은(는) CoddyKit의 무료 Android Academy 강의입니다. 이것은 6개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Android Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Android Academy 강의에는 총 6개의 강의가 포함되어 있습니다.

오류 처리가 중요한 이유

설명 없이 비정상 종료되거나 멈추는 앱은 제대로 작동하지 않는 것처럼 느껴집니다. 사용자는 무슨 일이 일어났는지, 다음에 무엇을 해야 하는지 알 수 없습니다.

좋은 오류 처리란 다음을 의미합니다.

  • 앱이 안정적으로 유지됩니다.
  • 사용자에게 명확한 메시지가 표시됩니다.
  • 사용자가 다시 시도하거나 필요한 작업을 수행할 수 있습니다.

이것이 별 2개짜리 앱 리뷰와 별 5개짜리 앱 리뷰의 차이입니다.

UI 상태 모델링

깔끔한 패턴은 sealed class로 가능한 모든 UI 상태를 모델링하는 것입니다.

  • Loading — 요청을 처리하는 중입니다.
  • Success(data) — 데이터를 사용할 수 있습니다.
  • Error(message) — 문제가 발생했습니다.

ViewModel이 이러한 상태 중 하나를 내보내면 UI가 해당 상태를 화면에 표시합니다.

Sealed Class UiState

가능한 모든 상태를 위한 sealed class를 정의합니다.

sealed class UiState<out T> {
    object Loading : UiState<Nothing>()
    data class Success<T>(val data: T) : UiState<T>()
    data class Error(val message: String) : UiState<Nothing>()
}

// In ViewModel:
private val _state = MutableLiveData<UiState<List<Post>>>()
val state: LiveData<UiState<List<Post>>> = _state

fun loadPosts() {
    _state.value = UiState.Loading
    viewModelScope.launch {
        try {
            val posts = withContext(Dispatchers.IO) { repo.getPosts() }
            _state.value = UiState.Success(posts)
        } catch (e: Exception) {
            _state.value = UiState.Error(e.message ?: "Unknown error")
        }
    }
}

UI에서 상태 표시하기

상태를 관찰하고 각 경우에 맞는 뷰를 표시합니다.

viewModel.state.observe(this) { state ->
    when (state) {
        is UiState.Loading -> {
            binding.progressBar.visibility = View.VISIBLE
            binding.recyclerView.visibility = View.GONE
            binding.tvError.visibility = View.GONE
        }
        is UiState.Success -> {
            binding.progressBar.visibility = View.GONE
            binding.recyclerView.visibility = View.VISIBLE
            adapter.submitList(state.data)
        }
        is UiState.Error -> {
            binding.progressBar.visibility = View.GONE
            binding.tvError.text = state.message
            binding.tvError.visibility = View.VISIBLE
        }
    }
}

Loading에 ProgressBar 사용하기

데이터를 기다리는 동안 ProgressBar를 표시합니다.

  • 회전하는 로더에는 android:indeterminate="true"를 사용합니다.
  • View.VISIBLE과 View.GONE 사이에서 표시 상태를 전환합니다.
  • GONE은 뷰를 보이지 않게만 하는 것이 아니라 레이아웃에서 제거하므로 공간도 차지하지 않습니다.

Snackbar와 Toast 비교

오류 메시지에는 Toast보다 Snackbar를 사용하는 것이 좋습니다.

  • Snackbar에는 작업 버튼(예: "다시 시도")을 추가할 수 있습니다.
  • 현재 화면에 연결되어 다른 앱 위에 떠 있지 않습니다.
  • 자동으로 사라지거나 탭했을 때 닫힙니다.

다시 시도 버튼이 있는 Snackbar

다시 시도 작업 버튼과 함께 오류를 표시합니다.

import com.google.android.material.snackbar.Snackbar

fun showError(message: String) {
    Snackbar.make(
        binding.root,  // root view of the screen
        message,
        Snackbar.LENGTH_INDEFINITE  // stays until dismissed
    ).setAction("Retry") {
        viewModel.loadPosts()  // retry the request
    }.show()
}

입력값 검증

사용자 입력을 서버로 보내기 전에 검증합니다.

  • 필드 아래에 인라인 오류를 표시하려면 error 속성이 있는 TextInputLayout을 사용합니다.
  • API를 호출하기 전에 빈 필드, 이메일 형식, 비밀번호 길이를 확인합니다.
  • 사용자가 입력을 시작하면 오류를 지웁니다.

TextInputLayout 오류

양식 필드에 인라인 입력값 검증 오류를 표시합니다.

fun validateAndSubmit() {
    val email = binding.etEmail.text.toString().trim()
    val password = binding.etPassword.text.toString()

    var hasError = false

    if (email.isBlank() || !email.contains("@")) {
        binding.tilEmail.error = "Enter a valid email"
        hasError = true
    } else {
        binding.tilEmail.error = null  // clear error
    }

    if (password.length < 6) {
        binding.tilPassword.error = "Minimum 6 characters"
        hasError = true
    } else {
        binding.tilPassword.error = null
    }

    if (!hasError) viewModel.login(email, password)
}

빠른 확인

뷰를 레이아웃에서 완전히 제거하여 공간을 차지하지 않게 하는 표시 상태는 무엇입니까?

복습: 오류 처리 및 UX

이제 앱에서 오류를 우아하게 처리할 수 있습니다.

  • sealed class로 Loading / Success / Error 상태 모델링
  • 로드 중에 ProgressBar 표시
  • 네트워크 오류에 대해 다시 시도 작업이 있는 Snackbar 표시
  • 양식 검증을 위한 TextInputLayout 인라인 오류
  • View.GONE과 View.INVISIBLE — 제거와 숨기기

마지막 강의에서는 앱을 Play 스토어에 게시합니다.

자주 묻는 질문

“오류 처리와 사용자 경험” 강의는 무료인가요?

네 — “오류 처리와 사용자 경험” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Android Academy 강의 전체를 잠금 해제할 수 있습니다. Android Academy 강의에는 총 6개의 강의가 포함되어 있습니다.

“오류 처리와 사용자 경험”에서 뭘 배우나요?

봉인 클래스로 UI 상태(Loading/Success/Error)를 모델링합니다. ProgressBar와 재시도 작업이 있는 Snackbar를 표시하고 TextInputLayout에서 인라인 유효성 검사 오류를 보여 줍니다. 브라우저에서 직접 실행하는 실습 코드로 Android Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Android Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Android Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 6개 중 3번째 강의입니다.

“오류 처리와 사용자 경험” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Android Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Android Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. Retrofit과 REST API
  2. Coil로 이미지 로드하기
  3. 오류 처리와 사용자 경험
  4. 푸시 알림
  5. WorkManager와 백그라운드 작업
  6. Play Store에 게시하기
← Android Academy(으)로 돌아가기