[Android/ViewModel] 활동 수명 주기에 관한 이해

hyihyi·2023년 10월 17일
0

ViewModel을 쓰는 이유 : UI 컨트롤러의 데이터를 캡슐화하여 구성이 변경되어도 데이터를 유지하기 위해서

1. 활동 수명 주기에 관한 이해

https://developer.android.com/topic/libraries/architecture/viewmodel?hl=ko#coroutines

사용자가 앱을 탐색하고, 앱에서 나가고, 앱으로 다시 돌아가면, 앱의 Activity 인스턴스는 수명 주기 안에서 서로 다른 상태를 통해 전환됩니다. Activity 클래스는 활동이 상태 변화(시스템이 활동을 생성, 중단 또는 다시 시작하거나, 활동이 있는 프로세스를 종료하는 등)를 알아차릴 수 있는 여러 콜백을 제공합니다.

각 콜백은 상태 변화에 적합한 특정 작업을 실행할 수 있도록 합니다. 적시에 알맞은 작업을 하고 적절하게 전환을 처리하면 앱이 더욱 안정적으로 기능할 수 있습니다. 예를 들어 수명 주기 콜백을 잘 구현하면 앱에서 다음과 같은 문제가 발생하지 않도록 예방하는 데 도움이 될 수 있습니다.

  • 사용자가 앱을 사용하는 도중에 전화가 걸려오거나 다른 앱으로 전환할 때 비정상 종료되는 문제
  • 사용자가 앱을 활발하게 사용하지 않는 경우 귀중한 시스템 리소스가 소비되는 문제
  • 사용자가 앱에서 나갔다가 나중에 돌아왔을 때 사용자의 진행 상태가 저장되지 않는 문제
  • 화면이 가로 방향과 세로 방향 간에 회전할 경우, 비정상 종료되거나 사용자의 진행 상태가 저장되지 않는 문제

1.1 활동 수명 주기 개념

활동 수명 주기 단계 간에 전환하기 위해 활동 클래스는 6가지 콜백으로 구성된 핵심 집합의 onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy()를 제공

1. onCreate()

이 콜백은 시스템이 먼저 활동을 생성할 때 실행되는 것으로, 필수적으로 구현해야 합니다.
onCreate() 메서드에서 활동의 전체 수명 주기 동안 한 번만 발생해야 하는 기본 애플리케이션 시작 로직을 실행합니다. 예를 들어 onCreate()를 구현하면 데이터를 목록에 바인딩하고, 활동을 ViewModel과 연결하고, 일부 클래스 범위 변수를 인스턴스화할 수도 있습니다.

onCreate에서는 사용자 인터페이스 선언(XML 레이아웃 파일에 정의됨), 멤버 변수 정의, 일부 UI 구성 등의 활동에 관한 기본 설정 등을 한다. 아래는 예시이다.

override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState)
    gameState = savedInstanceState?.getString(GAME_STATE_KEY)
    setContentView(R.layout.main_activity)
    textView = findViewById(R.id.text_view)
    
}

onCreate() 메서드가 실행을 완료하면 시작됨 상태가 되고, 시스템이 연달아 onStart()와 onResume() 메서드를 호출

2. onStart()

onStart()가 호출되면 활동이 사용자에게 표시
앱은 활동을 포그라운드에 보내 상호작용할 수 있도록 준비
onStart() 메서드는 매우 빠르게 완료되고, 생성됨 상태와 마찬가지로 활동은 시작됨 상태에 머무르지 않습니다. 이 콜백이 완료되면 활동이 재개됨 상태에 들어가고, 시스템이 onResume() 메서드를 호출

3. onResume()

이 상태에 들어갔을 때 앱이 사용자와 상호작용합니다. 어떤 이벤트가 발생하여 앱에서 포커스가 떠날 때까지 앱이 이 상태에 머무릅니다. 예를 들어 전화가 오거나, 사용자가 다른 활동으로 이동하거나, 기기 화면이 꺼지는 이벤트가 이에 해당합니다.
방해되는 이벤트가 발생하면 활동은 일시중지됨 상태에 들어가고, 시스템이 onPause() 콜백을 호출합니다.

4. onPause()

시스템은 사용자가 활동을 떠나는 것을 나타내는 첫 번째 신호로 이 메서드를 호출

5. onStop()

활동이 사용자에게 더 이상 표시되지 않을 때
앱이 사용자에게 보이지 않는 동안 앱은 필요하지 않은 리소스를 해제하거나 조정해야 합니다. 예를 들어 앱은 애니메이션을 일시중지하거나, 세밀한 위치 업데이트에서 대략적인 위치 업데이트로 전환할 수 있습니다.
활동은 정지됨 상태에서 다시 시작되어 사용자와 상호작용하거나, 실행을 종료하고 사라집니다. 활동이 다시 시작되면 시스템은 onRestart()를 호출합니다. Activity가 실행을 종료하면 시스템은 onDestroy()를 호출합니다.

6.onDestroy()

onDestroy()는 활동이 소멸되기 전에 호출됩니다. 시스템은 다음 중 하나에 해당할 때 이 콜백을 호출합니다.

(사용자가 활동을 완전히 닫거나 활동에서 finish()가 호출되어) 활동이 종료되는 경우
구성 변경(예: 기기 회전 또는 멀티 윈도우 모드)으로 인해 시스템이 일시적으로 활동을 소멸시키는 경우

위 영상처럼 화면 회전을 시키면 액티비티의 수명주기가 바뀐다.

🤔수명주기가 바뀌면 어떤 문제가 생길까?

간단한 계산기를 만들어서 확인해보자

화면 이동을 하는 순간 숫자의 값이 0으로 초기화되는 걸 확인할 수 있다.
안드로이드의 lifecycle이 바뀌면서 onCreate부터 실행돼 뷰가 다시 그려진다.
이런 상황일 때를 감지해서 코드를 짜줄 수 있겠지만 뷰모델을 사용하는 것이 편하다.

<MainActivity.kt>

class MainActivity : AppCompatActivity() {

    lateinit var viewModel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewModel = ViewModelProvider(this).get(MainViewModel::class.java)

        val plusBtn: Button = findViewById<Button>(R.id.button1)
        val minusBtn: Button = findViewById<Button>(R.id.button2)
        val result: TextView = findViewById<TextView>(R.id.text)
        result.text = viewModel.counterValue.toString()


        plusBtn.setOnClickListener {
            viewModel.plus()
            result.text = viewModel.counterValue.toString()
        }

        minusBtn.setOnClickListener {
            viewModel.minus()
            result.text = viewModel.counterValue.toString()
        }
    }
}

<MainViewModel.kt>

class MainViewModel: ViewModel() {

    var counterValue = 0

    fun plus(){
        counterValue++
    }

    fun minus(){
        counterValue--
    }
}

profile
자유롭게 쓴 나의 자유로운 Development voyage⛵

0개의 댓글