Android Lifecycle

강보훈·2021년 11월 29일
0

Activity

  • 사용자가 앱을 사용하고있고, 다시 돌아가거나, 종료하는 등 앱의 Activity 인스턴스는 수명 주기안에서 서로 다른 상태를 통해 전환된다. 따라서 이 상태 변화를 알아차릴 수 있는 콜백을 제공한다.
  • 수명 주기 콜백을 잘이용 할 경우 다음과 같은 문제 예방 가능
    • 앱 사용 도중 전화가 오거나 다른 앱으로 전활 시 비정상 종료
    • 앱을 활발하게 사용중이지 않을때 시스템 리소스 낭비
    • 사용자가 앱에서 나갔다 왔을 때 진행 상태 저장하지 않는 경우
    • 화면이 가로, 세로 회전 시 비정상 종료, 진행 상태가 저장되지 않음

활동 수명 주기

  • 몇몇 메소드들은 종속적인 메소드가 있다.

onCreate

  * 시스템이 먼저 활동을 생성할 때 실행됨
  * 필수적으로 구현해야 함
  * 전체 수명 주기 중 한 번만 발생해야하는 로직을 실행
  * `savedInstanceState` 매개변수를 수신하는데, 이는 활동의 이전 저장 상태가 포함된 `Bundle` 객체입니다. 이번에 처음 생성된 활동인 경우 Bundle 객체의 값은 null입니다.
  

onStart

  • 앱이 활동이 시작됨 상태에 들어감
  • 이 시점에서 사용자에게 표시되고, 상호작용할 수 있도록 준비함
  • onCreate와 마찬가지로 이 상태 주기에 머무르지 않고 이 활동이 마무리 되면 활동이 '재개됨'으로 되고 onResume을 호출한다.

onResume

  • 어떤 이벤트가 발생해서 앱에서 포커스가 떠날 때까지 이 상태에서 머무른다.
  • 활동이 재개됨 상태로 전환되면 이 화롱의 수명 주기와 연결된 모든 수명 주기 구성요소는 ON_RESUME 이벤트를 수신한다.
  • 방해되는 이벤트가 발생시 일시중지됨상태에 들어가고 onPause를 호출한다.
  • 활동이 일시중지됨 상태에서 다시 돌아오면 onResume메소드를 다시 실행하는데 onResume()을 구현하여 onPause() 중에 해제하는 구성요소를 초기화하고, 활동이 재개됨 상태로 전환될 때마다 필요한 다른 초기화 작업도 수행해야 한다.

onPause

  • 사용자가 활동을 떠나는 것을 나타내는 첫 신호
  • 활동이 이 상태에 들어가는 이유
    • 일부 이벤트가 앱 실행을 방해
    • Android 7.0(API 24)이상에서는 여러 앱이 멀티 윈도우 모드에서 실행된다. 그 중 하나만 포커스를 받을 수 있기에 나머지는 일시중지가 된다.
    • 새로운 반투명 활동(ex:대화상자)가 열린경우
  • 포그라운드에 있지 않을 때 실행할 필요가 없는 것들을 모두 정지할 수 있다.
  • 멀티윈도우 환경에서는 이 상태에서도 여전히 보이는 상태일 수 있다. 그러므로 UI 관련 리소스와 작업을 완전히 끝내거나 조정할 때는 onStop을 사용하는 것을 권장
  • onPause 실행이 끝나고 활동이 일시중지됨 상태로 남을 수 있고 활동이 다시 시작하거나 왼전히 보이지 않게 될 때까진 이 상태에서 머무른다.
  • 주의사항
    • onPause는 매우 잠깐 실행되므로 저장 작업을 하기에는 시간이 부족하다. 따라서 저장 작업, 네트워크 호출, DB 트랜잭션을 실행해서는 안된다

onStop

  • 활동이 더 이상 표시되지 않으면 중단됨상태에 들어가고 시스템은 onStop을 호출한다. 예를 들면 새로 시작된 활동이 화면 전체를 차지할 경우 적용이 된다.
  • 앱이 사용자에게 보이지 않은 동안 필요하지 않은 리소스를 해제하거나 조정해야 한다.
  • onStop을 이용하면 사용자가 멀티 윈도우 모드에서 활동을 보고 있더라도 UI 관련 작업이 계속해서 진행된다.
  • CPU를 비교적 많이 소모하는 종료 작업을 실행해야 한다. ex : DB에 데이터 저장
  • 활동이 중단됨 상태가 되면 Activity객체는 메모리 안에 머무른다
  • 활동이 다시 시작되면 onRestart를 호출하고 완전이 종료되면 onDestroy를 호출한다.

onDestroy

  • 활동이 소멸되기 전에 호출된다.
  • 호출되는 조건
    • (사용자가 활동을 완전히 닫거나 활동에서 finish()가 호출되어) 활동이 종료되는 경우
    • 구성 변경(예: 기기 회전 또는 멀티 윈도우 모드)으로 인해 시스템이 일시적으로 활동을 소멸시키는 경우
  • 활동에 소멸되는 이유를 결정하는 로직을 입력하는 대신 ViewModel 객체를 사용하여 활동의 관련 뷰 데이터를 포함해야 한다.
    • 활동이 구성 변경으로 인해 다시 생성될 경우 ViewModel은 그대로 보존되어 다음 활동 인스턴스에 전달되므로 추가 작업이 필요하지 않다.
    • 활동이 다시 생성되지 않을 경우 ViewModel은 onCleared 메서드를 호출하여 활동이 소멸되기 전에 모든 데이터를 정리해야 합니다.
    • 이 두 시나리오는 isFinishing 메소드로 구분이 가능하다.
  • 구성 변경으로 인해 onDestroy가 호출되는 경우 시스템이 즉시 새 활동 인스턴스를 생성한 다음, 새로운 구성에서 그 새로운 인스턴스에 관해 onCreate를 호출한다.

Activity 상태 및 메모리에서 제거

  • 시스템은 RAM에 여유 공간이 필요할 경우 프로세스를 종료한다. 시스템이 특정 프로세스를 종료할 가능성은 해당 프로세스의 활동 상태에 따라 달라진다.
  • 시스템은 절대 활동을 직접 종료하지 않는다. 대신 활동을 실행하는 프로세스를 죽이고 프로세스에서 실행되는 다른 모든 작업을 죽인다.

임시 UI 상태 저장 및 복원

  • 시스템 제약으로 인해 활동이 소멸되면 ViewModel, onSaveInstanceState() 및/또는 로컬 저장소를 결합하여 사용자의 임시 UI 상태를 보존해야 한다.

인스턴스 상태

  • 시스템 제약으로 인해 활동을 소멸시킨 경우 Activity 인스턴스는 사라지지만 시스템에 존재했다는 정보는 남아있다. 사용자가 다시 활동을 시작하려는 경우 이 정보를 이용해서 새로운 인스턴스를 생성한다.
  • 복원을 위해 사용되는 데이터를 인스턴스 상태라고 하며, Bundle 객체에 저장된 키-값 쌍의 컬렉션이다. 기본적으로는 Bundle 인스턴스를 이용해서 각 View 객체 관련 정보를 저장한다.
  • View를 복원하고 싶다면 각 View마다 고유 ID가 있어야한다. (android:id 속성)
  • Bundle 객체는 메인 스레드에서 직렬화되어야 하고 시스템 프로세스 메모리를 사용하므로 소량의 데이터를 보존하는 데만 적합하다.
  • 그 이상의 데이터는 영구 로컬 저장소, onSaveInstanceState() 메서드, ViewModel 클래스를 복합적으로 이용하는 것이 좋다.

onSaveInstanceState를 사용한 UI 상태 저장

  • 활동이 정지되기 시작하면 인스턴트 상태 번들에 정보 저장할 수 있게끔 시스템이 onSaveInstanceState를 호출한다.
  • 만약 영구 데이터를 저장하고 싶다면 포그라운드에 있을 때 기회를 잡고 안된다면 onStop 일 때 하는 것이 좋다.
override fun onSaveInstanceState(outState: Bundle?) {
    // Save the user's current game state
    outState?.run {
        putInt(STATE_SCORE, currentScore)
        putInt(STATE_LEVEL, currentLevel)
    }

    // Always call the superclass so it can save the view hierarchy state
    super.onSaveInstanceState(outState)
}

companion object {
    val STATE_SCORE = "playerScore"
    val STATE_LEVEL = "playerLevel"
}

저장된 인스턴스 상태를 사용해서 UI 상태 복원

  • 시스템이 활동에 전달하는 Bundle로부터 저장된 인스턴스 복구를 할 수 있다.
  • onCreate 와 onRestoreInstanceState 콜백 메소드 둘 다 동일한 Bundle을 수신한다.
    • onCreate
      • 새로 생성할수도, 재생성일 수도 있기때문에 Bundle의 Null 검사를 해야한다.
    • onRestoreInstanceState
      • onStart 이후에 호출된다.
      • 복원할 저장 상태가 있을 때만 호출되기에 Null 검사가 필요없다.
profile
신입 안드로이드 개발자입니다!

0개의 댓글