Activity, Fragment, AAC ViewModel, Lifecycle

유진·2024년 2월 17일
0
post-custom-banner

Activity

4대 컴포넌트 중 하나

  • 액티비티(Activity)
  • 서비스(Service)
  • 방송수신자(Broadcast Receiver)
  • 콘텐트 제공자(Content Provider)
  • class에서 Activity를 상속 받아 구현
  • 프레그먼트와 다르게 독립적으로 존재할 수 있음
  • manifest에 액티비티를 추가하여야 함! 안그러면 문제가 생김
  • 인텐트 필터
    • 인텐트 필터가 있으면 해당 액티비티를 독립적으로 실행할 수 있음 (빌드 하면 따로 아이콘이 생겨서 진입 가능)
  • 생명주기
표시 한 색깔끼리 세트로 기억하자~

1. OnCreate, OnDestroy
    - OnCreate는 액티비티가 실행될 때 딱 한 번만 실행된다. 처음 액티비티가 실행되면 view를 생성하고, onCreate에서 처리해야 할 일이 완료되면 OnStart, OnResume을 순서대로 실행한다.
    - OnDestroy는 View를 폐기하고, 액티비티를 실행하면서 사용한 리소스를 해제한다. 메모리에서 완전히 view를 폐기하는 단계로, OnDestory가 호출되면 앱이 완전히 종료되었다고 할 수 있다.
2. OnStart, OnStop, OnRestart
    - OnStart는 화면에 표시되기 직전 단계로 주로 통신하거나 센서 처리가 필요할 때 사용한다. 그리고 UI를 관리하는 코드를 초기화한다.
    - OnStop은 다른 액티비티가 현재 화면 전체를 가리거나, 액티비티가 중지될 때 호출된다. OnStop에서는 메모리가 부족한 경우, 강제 종료되어 OnCreate를 다시 호출하는 경우와 사용자가 다른 액티비티를 호출하여, 다시 돌아오는 경우 OnRestart를 호출하고 OnStart과정부터 시작하는 경우로 나뉜다.
    - OnRestart는 조금 특이한 형태로, OnStop에서 사용자가 다른 액티비티를 호출하고 다시 돌아오는 경우 OnRestart가 호출된다. 그리고 OnStart-OnResume을 거쳐 사용자에게 화면을 다시 보여준다.
3. OnResume, OnPause
    - OnResume은 사용자에게 화면이 보이는 단계이다. OnResume에서 사용자와 상호작용을 한다. 그리고 사용자가 다른 앱을 실행하거나 앱 종료, 화면이 꺼지기 등 방해 요소가 있기 전까지는 OnResume상태에 머무른다.
    - OnPause단계는 OnResume단계에서 방해 요소가 발생하면 OnPause단계로 넘어간다. OnPause단계에서 사용자가 다시 화면으로 돌아가면 OnResume을 호출하여 화면을 보여준다.

언제부터 UI 상호작용? onResume 부터~

Fragment

  • 재사용 가능 한 부분
  • 단독으로 실행될 수 없음
    • [BottomNavigationView](https://developer.android.com/reference/com/google/android/material/bottomnavigation/BottomNavigationView?hl=ko)[ViewPager2](https://developer.android.com/jetpack/androidx/releases/viewpager2?hl=ko)와 같은 일부 Android Jetpack 라이브러리는 프래그먼트와 호환되도록 설계되었습니다.
  • activity와 다른 별개의 생명주기를 가짐
(fragment = Activity+View)

| Activity, Fragment | • onCreate() | onDestroy() |
| --- | --- | --- |
| Fragment | • onCreateView() | onDestroyView() |
  • FragmentManager
    • 주로 프레그먼트 간의 이동을 할 때에 씀
      private fun changeBottomNavigationView(name: String?) {
              when (name) {
                  ApplicationClass.FRAGMENT_HOME_ID -> {
                      BottomNavigationUtil.setSelect(this, R.id.menu_main_btm_nav_home)
                  }
                  ...
       childFragmentManager.beginTransaction()
                          .add(R.id.container, GroupCategoryListFragment(childFragmentManager, this))
                          .addToBackStack(null)
                          .commit()
  • navigation
    • 근데 FragmentManager를 쓰지 말고 이제 jetpack의 navigation을 쓰라고 하심
    - Fragment간의 화면 이동 흐름(플로우)을 한 눈에 파악할 수 있다.
    - 화면 전환에 대한 표준화된 애니메이션 리소스를 사용할 수 있다.
    - 탐색 창, 하단 탐색 등 탐색 UI 패턴을 쉽게 구현할 수 있다.
    - 프래그먼트 트랜잭션을 처리할 수 있다.

    [https://velog.io/@sana/Android-Jetpack-Navigation-적용](https://velog.io/@sana/Android-Jetpack-Navigation-%EC%A0%81%EC%9A%A9)

    https://velog.io/@hoyaho/Jetpack-Navigation-Component
    
- 구성 요소
    1. **`Navigation Graph`**
        - `Navigation` 과 관련해 **모든 정보를 가지고 있는 구성 요소**로, 어떤 목적지들이 있는지, 이동 중 어떤 액션을 취할 것인지, 어떤 데이터를 넘겨줄 것인지에 대한 정보가 담겨져 있다.
        - `XML` 리소스를 작성할 수도, 코드로 직접 생성할 수도 있으나 보통은 위의 사진과 같이 비쥬얼 에디터를 제공하기 때문에 `XML` 로 주로 작성한다.
    2. **`NavHost`**
        - `Navigation Graph` 에 담겨져 있는 목적지, **즉 화면을 표현하는** 빈 컨테이너 공간이다.
            
            ```kotlin
            findNavController().navigate(action)
            ```
            
    3. **`NavController`**
        - 모든 `NavHost` 가 개별적으로 가지고 있는 구성 요소로, 이름에 맞게 `NavHost` 에 어떤 화면을 띄울 것인지 컨트롤하는 역할을 수행한다.
- Navigation 의 실행 절차
    
    `Navigation` 을 사용할 때 간단한 플로우는 아래와 같다.
    
    1. 특정 경로를 따라 이동할지, 특정 목적지로 직접 이동할 것인지 결정 후 `NavController` 에게 요청한다.
    2. `NavController` 는 `Navigation Graph` 내에서 적절한 목적지를 찾아 `NavHost` 에 표현한다.

---

AAC ViewModel

https://www.youtube.com/watch?v=3QrEa35-pu8

viewmodel vs AAC viewmodel

✨ 둘은 다르다! 그냥 이름만 같은 거임
  • viewmodel
    • view, viewmodel, model
  • aac-viewmodel
    • viewmodel provider를 통해 초기화
    • ui 업데이트 방법은 그림은 동일하지만 내부 구현은 전혀 다르다
  • viewmodel

    • 모델은 없는 경우도 있음
    • 뷰-뷰모델 사이에 데이터바인딩 (+live data) → xml에서 뷰모델을 바로 붙여서 데이터 갱신을 할 수 있음
    • observer 해서 데이터가 바뀌었는지 알려줌
    • DI를 활용하여 결합도를 줄일 수 있음
    • dataBinding으로 view와 의존도를 줄이기
  • AAC viewmodel

    • 목적: 화면 회전 시 데이터를 유지할 수 있는 구조로 디자인
      • 다크모드 전환도
      • 언어 설정도
    • 내부에서 lifecycle을 사용할 수 있도록 초기화
      • lifecycle의 onDestroy() 코드가 동작
        • ViewModel 내부의 onCleared() 호출을 통해 사용한 자원을 정리함
    • 구현: ViewModel(), AndroidViewModel(application) 을 상속받아 구현
    • 초기화: ViewModelProviders로 초기화
      • Activity / Fragment 2개 중에 하나로 초기화 가능
      • 기본 ViewModel 생성자 범위를 벗어나면 Factory를 상속받아 별도 구현
      • ViewModelProviders.of(this) → this
        • activity → activity lifecycle를 따름
        • fragment → fragment lifecycle를 따름

1 액티비티, 2프레그먼트 → requiredActivity 하면 액티비티의 라이프사이클을 따라감!

→ 프레그먼트 두 개에서 데이터 공유할 수 있는 방법!

✨ AAC ViewModel이 가지는 의미 - activity의 화면 회전 시 데이터 유지가 필요한 경우에 유용 - 1개의 activity에서 다중의 fragment에서 동일한 이벤트/데이터를 처리하고 싶을 경우 - onCleared에서 release가 필요하다

Lifecycle

  • 사용자가 앱을 사용하는 도중에 전화가 걸려오거나 다른 앱으로 전환할 때 비정상 종료되는 문제
  • 사용자가 앱을 활발하게 사용하지 않는 경우 귀중한 시스템 리소스가 소비되는 문제
  • 사용자가 앱에서 나갔다가 나중에 돌아왔을 때 사용자의 진행 상태가 저장되지 않는 문제
  • 화면이 가로 방향과 세로 방향 간에 회전할 경우, 비정상 종료되거나 사용자의 진행 상태가 저장되지 않는 문제 ⇒ lifecycle을 잘 지킬 경우 해결 볼 수 있음
profile
안드로이드 학생 개발자 에디 / 유진입니다
post-custom-banner

0개의 댓글