[안드로이드] Activity Lifecycle

Chloe Choi·2021년 3월 30일
0

안드로이드

목록 보기
9/17

배경

액티비티가 백스택에 push된 상태에서 메모리가 부족해져 시스템에 스택의 액티비티를 kill 하게 된 상황을 생각해보자.

만약 그 화면에 EditText 등 사용자 인터페이스 데이터가 포함되어있다면? 사용자가 다른 액티비티를 종료하고 스택의 액티비티를 포그라운드로 불러온다면 어떻게 될까?
👉 시스템은 새로운 액티비티 인스턴스를 생성하고 전의 데이터는 유실되어 없다.

매끄러운 전환을 위해 동적 상태를 저장하는 것이 필요하다.

이렇게 적시에 액티비티 상태를 저장, 복원하기 위해 생명주기가 고안되었다! 그리고 각 상황에 맞는 처리를 지원하기 위해 Lifecycle callbacks를 제공한다.

Lifecycle Callbacks

각 라이프사이클의 의미와 그에 따라 각 콜백에서 처리해야 할 일을 알아보자.

Back Stack
사용자에게 보이기 위해 갖는 구조로, FILO를 따르며 열린 순서대로 스택에 쌓임

  • 기본구조
  • 예시

onCreate

When

액티비티 인스턴스가 최초로 생성될 때

Features

  • 사용자는 필수적으로 구현해야 함
  • 매개변수로 넘어오는 savedInstanceState는 직전에 생성되었다가 소멸된 동일 액티비티 인스턴스의 동적상태 정보가 저장된 객체이다.
  • savedInstanceState 매개변수는 액티비티의 이전 저장상태를 포함하는 Bundle 객체
    따라서, 처음 생성된 액티비티의 경우, null 값을 가짐

What

👉 액티비티의 전체 생명주기 중 한 번만 발생해야하는 시작 로직을 구현해야함
ex. setContentView, 액티비티와 ViewModel연결, 일부 변수 초기화 등

onStart

When

액티비티의 생성이 완료되고 사용자 인터페이스가 곧 사용자에게 보여질 것(포그라운드로 보내지는 것)을 알림

Features

  • 빠르게 완료되는 상태

What

👉 통신이나 센서 처리 시작, UI 관리코드 초기화

onRestoreInstanceState

When

전에 onSaveInstanceState 콜백에서 액티비티 정보를 저장해 savedInstanceState가 null이 아닌경우에 onStart 뒤 호출

What

👉 savedInstanceState로 받은 데이터를 액티비티에 설정

onResume

When

스택 맨 위로 이동해 사용자와 상호작용이 일어날 때
(액티비티가 포그라운드로 올라가 사용자의 Focus를 잡았을 때)

Features

  • 앱에서 포커스가 떠날 때(전화수신, 사용자가 다른 액티비티로 이동 등)까지 이 상태

What

👉 사용자에게 보이는 동안 실행해야 하는 모든 기능을 활성화(필요한 애니메이션 실행 등의 화면 갱신 처리, 카메라 미리보기 시작)

onSaveInstanceState

When

현재의 동적상태 데이터를 저장할 수 있게 액티비티가 소멸되기 직전에 호출

Features

  • 동적상태 데이터가 저장될 필요가 있다는 것을 런타임에 알 경우에만 이 메서드가 호출됨
  • 액티비티가 pause된 동안 시스템이 프로세스를 소멸시키더라도 Bundle에 View객체 상태를 그대로 저장함. 그리고 이를 사용자가 해당 액티비티로 돌아오면 이를 복원함! 이런 값은 신경쓰지 않아도 됨!

What

👉 Bundle 객체를 전달받으면 그 객체에 데이터를 넣음 참고

onPause

When

액티비티 위에 다른 액티비티가 백스택에 올라와서 Focus를 잃었을 때 호출

Features

  • 보이기는 하지만 사용자와 interaction할 수 없는 상태(일부분이 보이거나 새로운 액티비티가 투명한 경우)
  • 멀티모드인 경우에도 해당
    따라서, UI 관련 리소스와 작업을 완전히 해제하거나 조정할 때는 onPause대신 onStop을 사용하는 게 좋음
  • 이때 다시 액티비티로 돌아가면 onResume으로 돌아가 화면 호출
  • 액티비티가 다시 시작되거나 사용자에게 완전히 보이지 않게 될 때까지 이 상태
  • 아주 잠깐 실행되므로 데이터를 저장하기엔 시간이 부족
    따라서, 앱 또는 사용자 데이터를 저장, 네트워크 호출, 디비 트랜잭션 실행에 부적합(onStop에서 진행하세요!)

What

👉 액티비티가 pause상태일 때 잠시 일시중지여야 하는 것들을 일시중지 및 조정
ex. GPS, 시스템리소스 등 일시 해제

onStop

When

사용자에게 보이지 않을 때

Features

  • 새로 시작된 액티비티가 화면 전체를 차지하는 경우
  • 해당 액티비티 객체는 메모리 안에 머무르게 됨
  • 액티비티가 다시 시작되면 onRestart로,
    그대로 실행 종료되면 onDestroy로 감

What

👉 화면에 해당 액티비티가 보이지 않을 때 실행할 필요가 없는 기능을 모두 정지
ex. 애니메이션 일시중지, 디비에 정보 저장 작업

onRestart

When

유저가 해당 액티비티로 다시 돌아갈 때

What

👉 보통 아무 작업 안 함

onDestroy

When

액티비티가 소멸되기 전 호출
단, 두 상황 중 하나에 해당할 때 호출
1. 사용자가 액티비티를 완전히 닫거나, 액티비티에서 finish()를 호출해 액티비티가 종료되는 경우
2. Configure 변경(기기회전, 멀티윈도우 모드 등)으로 인해 시스템에 일시적으로 액티비티를 소멸시키는 경우

Features

  • 두 번째 상황의 경우, ViewModel에 액티비티의 뷰 데이터를 포함해 보존해야 함
    -> ViewModel 해제는 어디서? onClear!

What

👉 onStop, onPause에서 해제되지 않은 모든 리소스를 해제해야 함
ex. 필요없는 리소스 해제, 액티비티 참조 정리

리소스 초기화 / 해제

어떤 빌드업 이벤트에서 초기화 작업을 실행하든 빌드업 이벤트에 상응하는 수명 주기 이벤트를 사용하여 리소스를 해제해야함

  • ON_START <-> ON_STOP
  • ON_RESUME <-> ON_PAUSE

생명주기 콜백 호출 순서

  1. 시작할 때
    onCreate -> onStart -> onResume
  2. 화면 회전할 때(Configure 변경)
    onPause -> onStop -> onDestroy -> onCreate -> onStart -> onResume
  3. 다른 액티비티가 위로 뜰 때, 홈키 등
    onPause(잠깐) -> onStop

    다른 액티비티 상태도 같이 체크해보자
    [액티비티A가 액티비티B를 startActivity()로 호출]
    1.액티비티A 생성
    A onCreate - A onStart - A onResume
    2.startActivity() 호출
    A onPause - B onCreate - B onStart - B onResume - A onStop
    3.press back key
    B onPause - A onRestart - A onStart - A onResume - B onStop - B onDestroy
    +) 액티비티B가 호출되고 액티비티B의 onStart에서 finish() 호출
    A onPause - B onCreate - B onStart - A onResume - B onStop - B onDestroy

    왜 이럴까?
    onStop은 뷰에서 보이지 않을때까지 호출되지 않는다. 따라서, 다른 액티비티가 화면을 가리기 전까지 onStop은 호출되지 않는다.

  4. back 키로 액티비티 종료
    onPause -> onStop -> onDestroy
  5. back 키로 기존 액티비티로 돌아올 때(원래는 onStop에)
    onRestart -> onStart -> onResume
  6. 투명 액티비티가 위로 뜰 때
    onPause

액티비티가 아닌 다른곳에서 액티비티의 상태를 알아야한다면?

LifecycleObserver
👉 이 방법을 통해 크고 복잡한 코드를 쪼갤 수 있다

ref.

https://stackoverflow.com/questions/9963381/android-activity-lifecycle-state-order-when-new-activity-starts
https://developer.android.com/guide/components/activities/activity-lifecycle#tba

profile
똑딱똑딱

0개의 댓글