Android 아키텍처 권장사항 (뷰)

개념 및 Jetpack Compose 구현

이 페이지에서는 여러 아키텍처 권장사항을 설명합니다. 앱의 품질과 견고성, 확장성을 개선하는 데 참고하세요. 이를 통해 앱을 더 쉽게 유지관리하고 테스트할 수도 있습니다.

UI 레이어

UI 레이어의 역할은 화면에 애플리케이션 데이터를 표시하고 사용자 상호작용의 기본 지점으로 기능하는 것입니다. 다음은 UI 레이어에 관한 권장사항입니다.

  • 단일 데이터 소스만 포함하더라도 저장소를 만들어야 합니다.
  • 작은 앱에서는 data 패키지 또는 모듈에 데이터 레이어 유형을 배치할 수 있습니다.

권장사항

설명

단방향 데이터 흐름(UDF)을 따릅니다.

적극 권장됨

단방향 데이터 흐름(UDF) 원칙을 따릅니다. 여기서 ViewModel은 관찰자 패턴을 사용하여 UI 상태를 노출하고 메서드 호출을 통해 UI에서 작업을 수신합니다.

앱에 이점이 적용되는 경우 AAC ViewModel을 사용합니다.

적극 권장됨

AAC ViewModel을 사용하여 비즈니스 로직을 처리하고, 애플리케이션 데이터를 가져와 UI 상태를 UI에 노출합니다.

자세한 ViewModel 권장사항 확인하기

ViewModel의 이점 확인하기

수명 주기 인식 UI 상태 컬렉션을 사용합니다.

적극 권장됨

적절한 수명 주기 인식 코루틴 빌더 repeatOnLifecycle를 사용하여 UI에서 UI 상태를 수집합니다.

repeatOnLifecycle에 대해 자세히 알아보세요.

ViewModel에서 UI로 이벤트를 전송하면 안 됩니다.

적극 권장됨

ViewModel에서 즉시 이벤트를 처리하고 이벤트 처리 결과로 상태 업데이트를 발생시킵니다. UI 이벤트에 관해 자세히 알아보세요.

단일 활동 애플리케이션을 사용합니다.

추천

앱에 화면이 두 개 이상 있으면 Navigation Fragments를 사용하여 화면 간에 이동하고 딥 링크로 앱에 연결합니다.

다음 스니펫은 수명 주기 인식 방식으로 UI 상태를 수집하는 방법을 설명합니다.

class MyFragment : Fragment() {

    private val viewModel: MyViewModel by viewModel()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        viewLifecycleOwner.lifecycleScope.launch {
            viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.uiState.collect {
                    // Process item
                }
            }
        }
    }
}

ViewModel

ViewModel은 UI 상태와 데이터 레이어 액세스 권한을 제공합니다. 다음은 ViewModel 권장사항입니다.

권장사항

설명

ViewModel은 Android 수명 주기에 구애받지 않아야 합니다.

적극 권장됨

ViewModel은 Lifecycle 관련 유형에 대한 참조를 보유해서는 안 됩니다. Activity, Fragment, Context 또는 Resources를 종속 항목으로 전달하면 안 됩니다. ViewModel에 Context가 필요한 경우 올바른 레이어에 있는지 적극적으로 평가해야 합니다.

코루틴 및 흐름을 사용합니다.

적극 권장됨

ViewModel은 다음을 사용하여 데이터 또는 도메인 레이어와 상호작용합니다.

  • 애플리케이션 데이터 수신을 위한 Kotlin 흐름
  • viewModelScope를 사용하여 작업을 실행하는 suspend 함수

화면 수준에서 ViewModel을 사용합니다.

적극 권장됨

UI의 재사용 가능한 부분에서 ViewModel을 사용하면 안 됩니다. 다음에서 ViewModel을 사용해야 합니다.

  • 뷰의 활동/프래그먼트
  • Jetpack Navigation을 사용하는 경우 대상 또는 그래프

AndroidViewModel를 사용하지 마세요.

적극 권장됨

AndroidViewModel이 아닌 ViewModel 클래스를 사용합니다. Application 클래스는 ViewModel에서 사용하면 안 됩니다. 대신 종속 항목을 UI 또는 데이터 레이어로 이동합니다.

UI 상태를 노출합니다.

추천

ViewModel은 단일 속성 uiState를 통해 UI에 데이터를 노출해야 합니다. UI에 관련 없는 여러 데이터가 표시되면 ViewModel은 여러 UI 상태 속성을 노출할 수 있습니다.

  • uiStateStateFlow로 만들어야 합니다.
  • 계층 구조의 다른 레이어에서 데이터 스트림으로 데이터가 제공되는 경우 WhileSubscribed(5000) 정책 ()과 함께 stateIn 연산자를 사용하여 uiState를 만들어야 합니다.
  • 데이터 레이어에서 발생하는 데이터 스트림이 없는 더 간단한 사례의 경우 변경 불가능한 StateFlow로 노출된 MutableStateFlow를 사용해도 됩니다.
  • 데이터, 오류, 로드 신호가 포함될 수 있는 데이터 클래스로 ${Screen}UiState를 보유할 수 있습니다. 이 클래스는 다른 상태가 배타적일 경우 봉인 클래스일 수도 있습니다.

다음 스니펫은 ViewModel에서 UI 상태를 노출하는 방법을 설명합니다.

@HiltViewModel
class BookmarksViewModel @Inject constructor(
    newsRepository: NewsRepository
) : ViewModel() {

    val feedState: StateFlow<NewsFeedUiState> =
        newsRepository
            .getNewsResourcesStream()
            .mapToFeedState(savedNewsResourcesState)
            .stateIn(
                scope = viewModelScope,
                started = SharingStarted.WhileSubscribed(5_000),
                initialValue = NewsFeedUiState.Loading
            )

    // ...
}

수명 주기

다음은 Android 수명 주기를 사용하기 위한 권장사항입니다.

권장사항

설명

활동 또는 프래그먼트에서 수명 주기 메서드를 재정의하면 안 됩니다.

적극 권장됨

활동이나 프래그먼트에서 onResume과 같은 수명 주기 메서드를 재정의하면 안 됩니다. 대신 LifecycleObserver를 사용하세요. 수명 주기가 특정 Lifecycle.State에 도달할 때 앱에서 작업을 실행해야 하는 경우 repeatOnLifecycle API를 사용합니다.

다음 스니펫은 특정 수명 주기 상태에서 작업을 실행하는 방법을 설명합니다.

class MyFragment: Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
            override fun onResume(owner: LifecycleOwner) {
                // ...
            }
            override fun onPause(owner: LifecycleOwner) {
                // ...
            }
        }
    }
}