Activity 수명 주기는 Activity가 처음 초기화될 때부터 마지막으로 파괴되고 시스템이 메모리를 회수할 때까지 Activity가 거칠 수 있는 다양한 상태로 구성됩니다. 사용자가 앱을 시작하고, Activity 사이를 탐색하고, 앱 내부와 외부를 탐색하고, 앱을 나가면 Activity의 상태가 변경됩니다. 아래 다이어그램은 모든 Activity 수명 주기 상태를 보여줍니다. 이름에서 알 수 있듯이 이러한 상태는 Activity의 상태를 나타냅니다.
Activity 수명 주기 상태가 변경되면 일부 동작을 변경하거나 일부 코드를 실행하려는 경우가 많습니다. 따라서 Activity 클래스 자체와 AppCompatActivity와 같은 Activity의 모든 하위 클래스는 일련의 수명 주기 콜백 메서드를 구현합니다. Android는 활동이 한 상태에서 다른 상태로 이동할 때 이러한 콜백을 호출하며, 자체 활동에서 이러한 메서드를 재정의하여 이러한 수명 주기 상태 변경에 대한 응답으로 작업을 수행할 수 있습니다. 다음 다이어그램은 사용 가능한 재정의 가능한 콜백과 함께 수명 주기 상태를 보여줍니다.
프래그먼트에도 수명 주기가 있습니다. 프래그먼트의 수명 주기는 Activity의 수명 주기와 유사하므로 학습한 내용 중 많은 부분이 두 가지 모두에 적용됩니다. Activity 수명 주기는 Android의 기본 부분이며 간단한 앱에서 관찰하기 가장 쉽기 때문입니다. 다음은 프래그먼트 수명 주기에 대한 해당 다이어그램입니다.
이러한 콜백이 호출되는 시기와 각 콜백 메서드에서 수행할 작업을 아는 것이 중요합니다. 그러나 이 두 다이어그램은 모두 복잡하고 혼란스러울 수 있습니다. 여기서는 각 상태와 콜백이 의미하는 바를 읽는 대신 몇 가지 조사 작업을 수행하고 진행 상황에 대한 이해를 구축할 것입니다.
Android 수명 주기에 무슨 일이 일어나고 있는지 파악하려면 다양한 수명 주기 메서드가 호출되는 시기를 아는 것이 도움이 됩니다. 이것은 DessertClicker에서 문제가 발생하는 위치를 찾는 데 도움이 됩니다.
이를 수행하는 간단한 방법은 Android 로깅 API를 사용하는 것입니다. 로깅을 사용하면 앱이 실행되는 동안 콘솔에 짧은 메시지를 작성할 수 있으며 이를 사용하여 다른 콜백이 트리거될 때 표시할 수 있습니다.
활동 수명 주기 다이어그램에서 이 콜백을 이전에 사용한 적이 있기 때문에 onCreate() 메서드를 인식했을 수 있습니다. 모든 Activity가 구현해야 하는 유일한 메서드입니다. onCreate() 메서드는 Activity에 대해 일회성 초기화를 수행해야 하는 곳입니다. 예를 들어 onCreate()에서 레이아웃을 확장하거나 클릭 리스너를 정의하거나 데이터 바인딩을 설정합니다.
onCreate() 수명 주기 메서드는 Activity가 초기화된 직후(메모리에 새 Activity 객체가 생성될 때) 한 번 호출됩니다. onCreate()가 실행된 후 Activity가 생성된 것으로 간주됩니다.
참고: onCreate() 메서드는 재정의입니다. 수명 주기 메서드를 재정의하는 경우 즉시 super.onCreate()를 호출해야 합니다.
Log.i("MainActivity", "onCreate Called")
Log 클래스는 Logcat에 메시지를 씁니다. 이 명령에는 세 부분이 있습니다.
Log.메세지의 심각도(로그 태그, 실제 로그 메세지)
DessertClicker 앱을 컴파일하고 실행합니다. 디저트를 탭할 때 앱에서 동작 차이가 표시되지 않습니다. Android Studio의 화면 하단에서 Logcat 탭을 클릭합니다.
Logcat은 메시지 로깅을 위한 콘솔입니다. Log.i() 메서드 또는 다른 Log 클래스 메서드를 사용하여 명시적으로 로그에 보내는 메시지를 포함하여 앱에 대한 Android의 메시지가 여기에 표시됩니다.
Logcat 창에서 검색 필드에 I/MainActivity를 입력합니다.
Logcat에는 많은 메시지가 포함될 수 있으며 대부분은 사용자에게 유용하지 않습니다. 다양한 방법으로 Logcat 항목을 필터링할 수 있지만 검색이 가장 쉽습니다. MainActivity를 코드에서 로그 태그로 사용했으므로 해당 태그를 사용하여 로그를 필터링할 수 있습니다. 시작 부분에 I/를 추가하는 것은 이것이 Log.i()에 의해 생성된 정보 메시지임을 의미합니다.
로그 메시지에는 날짜와 시간, 패키지 이름(com.example.android.dessertclicker), 로그 태그(시작 부분에 I/ 포함) 및 실제 메시지가 포함됩니다. 이 메시지가 로그에 나타나므로 onCreate()가 실행되었음을 알 수 있습니다.
onStart() 수명 주기 메서드는 onCreate() 직후에 호출됩니다. onStart()가 실행된 후 Activity가 화면에 표시됩니다. Activity를 초기화하기 위해 한 번만 호출되는 onCreate()와 달리 onStart()는 Activity의 수명 주기에서 여러 번 호출될 수 있습니다.
onStart()는 onStop() 수명 주기 메서드와 쌍을 이룹니다. 사용자가 앱을 시작한 다음 기기의 홈 화면으로 돌아가면 Activity가 중지되고 더 이상 화면에 표시되지 않습니다.
Android Studio에서 MainActivity.kt를 연 상태에서 코드 > 메서드 재정의를 선택하거나 Ctrl+o를 누릅니다. 이 클래스에서 재정의할 수 있는 모든 메서드의 방대한 목록이 포함된 대화 상자가 나타납니다.
검색하려면 onStart를 입력하기 시작합니다. 일치하는 다음 항목으로 스크롤하려면 아래쪽 화살표를 사용합니다. 목록에서 onStart()를 선택하고 확인을 클릭하여 재정의 코드를 삽입합니다. 코드는 다음과 같습니다.
override fun onStart() {
super.onStart()
}
팁: Android Studio는 재정의된 메서드 코드를 클래스에서 다음으로 사용 가능한 적절한 위치에 삽입합니다. 수명 주기 재정의를 특정 위치(예: 클래스 끝 부분)에 두려면 재정의 메서드를 사용하기 전에 삽입 지점을 설정하세요.
override fun onStart() {
super.onStart()
Log.i("MainActivity", "onStart Called")
}
DessertClicker 앱을 컴파일 및 실행하고 Logcat 창을 엽니다. 검색 필드에 I/MainActivity를 입력하여 로그를 필터링합니다. onCreate() 및 onStart() 메서드가 차례로 호출되었으며 Activity가 화면에 표시됩니다.
기기의 홈 버튼을 누른 후 최근 화면을 이용하여 활동으로 돌아갑니다. 활동은 모두 동일한 값으로 중단된 위치에서 다시 시작되고 onStart()는 Logcat에 두 번째로 기록됩니다. 또한 onCreate() 메서드는 일반적으로 다시 호출되지 않습니다.
참고: 장치를 실험하고 수명 주기 콜백을 관찰할 때 장치를 회전할 때 비정상적인 동작을 확인할 수 있습니다. 다음에서 해당 동작에 대해 알아봅니다.
이 작업에서는 Timber라는 널리 사용되는 로깅 라이브러리를 사용하도록 앱을 수정합니다. Timber는 내장 Android Log 클래스에 비해 몇 가지 장점이 있습니다.
implementation 'com.jakewharton.timber:timber:4.7.1'
이 단계에서는 Application 클래스를 만듭니다. Application은 전체 앱에 대한 전역 애플리케이션 상태를 포함하는 기본 클래스입니다. 또한 운영 체제가 앱과 상호 작용하는 데 사용하는 주요 개체입니다. 지정하지 않으면 Android에서 사용하는 기본 Application 클래스가 있으므로 앱을 만들기 위해 특별한 작업을 수행할 필요 없이 항상 앱에 대해 생성된 Application 개체가 있습니다.
Timber는 전체 앱이 이 로깅 라이브러리를 사용하고 다른 모든 것이 설정되기 전에 라이브러리를 한 번 초기화해야 하기 때문에 Application 클래스를 사용합니다. 이와 같은 경우 Application 클래스를 하위 클래스로 분류하고 고유한 사용자 정의 구현으로 기본값을 재정의할 수 있습니다.
경고: 클래스는 모든 활동보다 먼저 생성되고 전역 상태를 보유할 수 있기 때문에 Application 클래스에 고유한 코드를 추가하고 싶을 수 있습니다. 그러나 전역적으로 사용 가능한 읽기 및 쓰기 가능한 정적 변수를 만드는 것은 오류가 발생하기 쉬운 것처럼 Application 클래스를 남용하기 쉽습니다. 코드가 실제로 필요한 경우가 아니면 Application 클래스에 활동 코드를 넣지 마십시오.
애플리케이션 클래스를 생성한 후에는 Android 매니페스트에서 클래스를 지정해야 합니다.
1. 디저트 클릭커 패키지에서 ClickerApplication이라는 새로운 Kotlin 클래스를 생성합니다.
package com.example.android.dessertclicker
class ClickerApplication {
}
class ClickerApplication : Application() {
}
class ClickerApplication : Application() {
override fun onCreate() {
super.onCreate()
}
}
override fun onCreate() {
super.onCreate()
Timber.plant(Timber.DebugTree())
}
이 코드는 Activity에서 라이브러리를 사용할 수 있도록 앱의 Timber 라이브러리를 초기화합니다.
<application
android:name=".ClickerApplication"
....
>
참고: Android 매니페스트에 사용자 지정 애플리케이션 클래스를 추가하지 않으면 앱이 오류 없이 실행됩니다. 그러나 앱은 클래스를 사용하지 않으며 Timber의 로깅 정보는 절대 볼 수 없습니다.
이 단계에서는 Timber를 사용하도록 Log.i() 호출을 변경한 다음 다른 모든 수명 주기 메서드에 대한 로깅을 구현합니다.
Timber.i("onCreate called")
Log 클래스와 마찬가지로 Timber도 정보 메시지에 i() 메서드를 사용합니다. Timber를 사용하면 로그 태그를 추가할 필요가 없습니다. Timber는 자동으로 클래스 이름을 로그 태그로 사용합니다.
onStart()메서드도 똑같이 바꿉니다.
DessertClicker 앱을 컴파일 및 실행하고 Logcat을 엽니다. onCreate() 및 onStart()에 대해 여전히 동일한 로그 메시지가 표시되지만 이제는 Log 클래스가 아닌 Timber에서 이러한 메시지를 생성하고 있습니다.
MainActivity에서 나머지 수명 주기 메서드를 재정의하고 각각에 대해 Timber 로그 문을 추가합니다. 코드는 다음과 같습니다.
override fun onResume() {
super.onResume()
Timber.i("onResume Called")
}
override fun onPause() {
super.onPause()
Timber.i("onPause Called")
}
override fun onStop() {
super.onStop()
Timber.i("onStop Called")
}
override fun onDestroy() {
super.onDestroy()
Timber.i("onDestroy Called")
}
override fun onRestart() {
super.onRestart()
Timber.i("onRestart Called")
}
Activity가 처음부터 시작되면 다음 세 가지 수명 주기 콜백이 모두 순서대로 호출되는 것을 볼 수 있습니다.
onResume() 메서드는 재개할 항목이 없더라도 시작 시 호출됩니다.
Error: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.16.
컴파일 후 실행하려니 에러가 발생했다. 코틀린 버전 문제인것 같아서 build.gradle(Project)에서 ext.kotlin_version을 최신 버전으로 높혀줬더니 문제가 해결되었다.
가장 기본적인 사용 사례부터 시작합니다. 앱을 처음으로 시작한 다음 앱을 완전히 종료하는 것입니다.
컵케이크를 몇번 클릭해봅니다.
기기에서 뒤로 버튼을 탭합니다. Logcat에서 onPause(), onStop() 및 onDestroy()가 순서대로 호출됩니다.
이 경우 뒤로 버튼을 사용하면 Activity(및 앱)가 완전히 닫힙니다. onDestroy() 메소드의 실행은 Activity가 완전히 종료되었고 Garbage Collet가 될 수 있음을 의미합니다. 가비지 컬렉션은 더 이상 사용하지 않을 개체의 자동 정리를 의미합니다. onDestroy()가 호출된 후 OS는 해당 리소스를 삭제할 수 있음을 알고 해당 메모리 정리를 시작합니다.
코드가 Activity의 finish() 메서드를 수동으로 호출하거나 사용자가 앱을 강제 종료하는 경우에도 Activity가 완전히 종료될 수 있습니다. (예를 들어, 사용자는 창 모서리에 있는 X를 클릭하여 최근 화면에서 앱을 강제 종료할 수 있습니다.) Android 시스템은 또한 앱이 한동안 화면에 표시되지 않은 경우 자체적으로 Activity를 종료할 수 있습니다. Android는 배터리를 절약하고 앱의 리소스를 다른 앱에서 사용할 수 있도록 하기 위해 이 작업을 수행합니다.
최근 화면을 사용하여 앱으로 돌아갑니다. 다음은 Logcat입니다.
Activity는 이전 단계에서 소멸되었으므로 앱으로 돌아가면 Android에서 새 Activity를 시작하고 onCreate(), onStart() 및 onResume() 메서드를 호출합니다. 이전 Activity에서 주문한 디저트 항목의 수와 총 가격은 유지되지 않았습니다. 0으로 재설정됩니다. 앱에서 이 동작을 원하지 않을 수 있습니다. 이 문제는 다음에 해결해 볼 것입니다.
여기서 핵심은 onCreate() 및 onDestroy()가 단일 Activity 인스턴스의 수명 동안 한 번만 호출된다는 것입니다. onCreate()는 앱을 처음으로 초기화하고 onDestroy()는 앱에서 사용하는 리소스를 정리합니다.
onCreate() 메서드는 중요한 단계입니다. 여기에서 모든 최초 초기화가 진행되고, 레이아웃을 확장(inflate)하여 처음으로 레이아웃을 설정하고, 변수를 초기화합니다.
이제 앱을 시작하고 완전히 닫았으므로 Activity가 처음 생성될 때 대부분의 수명 주기 상태를 보았습니다. 또한 Activity가 완전히 종료되고 파괴될 때 진행되는 모든 수명 주기 상태를 보았습니다. 그러나 사용자는 Android 기반 장치와 상호 작용할 때 앱 간 전환, 홈으로 돌아가기, 새 앱 시작, 전화 통화와 같은 기타 외부 활동으로 인한 중단 처리와 같은 다양한 작업을 수행합니다.
사용자가 해당 Activity에서 벗어날 때마다 Activity가 완전히 종료되지는 않습니다.
Activity가 더 이상 화면에 표시되지 않는 경우 이를 Activity를 Background에 배치하는 것으로 알려져 있습니다. (반대는 Activity가 Foreground나 화면에 있을 때입니다.)
사용자가 앱으로 돌아오면 동일한 Activity가 다시 시작되고 다시 표시됩니다. 수명 주기의 이 부분을 앱의 가시적 수명 주기(visible lifecycle)라고 합니다.
앱이 Background에 있을 때 시스템 리소스와 배터리 수명을 보존하기 위해 활발히 실행되어서는 안 됩니다. Activity 수명 주기와 해당 콜백을 사용하여 진행 중인 작업을 일시 중지하여 앱이 Background로 이동할 때를 알 수 있습니다. 그런 다음 앱이 Foreground로 전환되면 해당 작업을 다시 시작합니다.
예를 들어 컴퓨팅 리소스에 크게 의존하는 앱을 생각해 보십시오. 이 앱은 기기의 CPU를 사용하여 많은 계산을 할 수 있습니다. 처리 능력과 배터리 수명은 일반적으로 모바일 장치에서 제한되므로 Android 런타임 시스템은 리소스의 균형을 맞춰야 합니다. Background 프로세스가 성능을 저하시키거나 휴대폰 배터리를 조기에 소모할 수 있으므로 Android는 Foreground에서 실행되지 않는 앱에 대한 리소스 사용을 중지할 수 있습니다.
이 다음 단계에서는 앱이 Background로 갔다가 다시 Foreground로 돌아갈 때의 활동 수명 주기를 살펴봅니다.
DessertClicker 앱을 실행한 상태에서 컵케이크를 몇 번 클릭합니다.
기기의 홈 버튼을 누르고 Android Studio에서 Logcat을 관찰합니다. onPause() 메서드와 onStop() 메서드가 호출되지만 onDestroy()는 호출되지 않습니다. 홈 화면으로 돌아가면 앱이 완전히 종료되지 않고 앱이 Background로 전환됩니다.
onPause()가 호출되면 앱에 더 이상 포커스가 없습니다. onStop() 후에는 앱이 더 이상 화면에 표시되지 않습니다. Activity가 중지되었지만 Activity 개체는 여전히 Background에서 메모리에 있습니다. Activity는 파괴되지 않았습니다. 사용자가 앱으로 돌아갈 수 있으므로 Android는 주변에 활동 리소스를 유지합니다.
최근 화면을 사용하여 앱으로 돌아갑니다. Logcat에서 활동이 onRestart() 및 onStart()로 다시 시작된 다음 onResume()으로 다시 시작되었음을 알 수 있습니다.
기기의 최근 화면에 몇 개의 앱이 표시되도록 DessertClicker 이외의 앱을 하나 이상 시작하세요.
최근 화면을 불러오고 다른 최근 활동을 엽니다. 그런 다음 최근 앱으로 돌아가서 DessertClicker를 다시 Foreground로 가져옵니다.
여기에서 홈 버튼을 눌렀을 때와 동일한 콜백이 Logcat에 표시됩니다. onPause() 및 onStop()은 앱이 백그라운드로 들어갈 때 호출되고, 다시 돌아올 때 onRestart(), onStart(), onResume()이 호출됩니다.
여기서 중요한 점은 사용자가 Activity를 탐색할 때 onStart() 및 onStop()이 여러 번 호출된다는 것입니다. 앱이 Background로 이동할 때 앱을 중지하거나 Foreground로 돌아갈 때 다시 시작하려면 이러한 메서드를 재정의해야 합니다.
그렇다면 onRestart()는 어떻습니까? onRestart() 메서드는 onCreate()와 매우 유사합니다. Activity가 표시되기 전에 onCreate() 또는 onRestart()가 호출됩니다. onCreate() 메서드는 처음에만 호출되고 onRestart()는 그 이후에 호출됩니다. onRestart() 메서드는 활동이 처음 시작되지 않는 경우에만 호출하려는 코드를 넣는 곳입니다.
앱이 시작되고 onStart()가 호출되면 앱이 화면에 표시된다는 것을 배웠습니다. 앱이 다시 시작되고 onResume()이 호출되면 앱이 사용자 포커스를 얻습니다. 앱이 완전히 화면에 표시되고 사용자 포커스가 있는 수명 주기 부분을 대화형 수명 주기(interactive lifecycle)라고 합니다.
앱이 백그라운드로 전환되면 onPause() 이후에 포커스가 사라지고 onStop() 이후에는 앱이 더 이상 표시되지 않습니다.
포커스와 가시성의 차이는 활동이 화면에 부분적으로 표시될 수 있지만 사용자 포커스가 없을 수 있기 때문에 중요합니다. 이 단계에서는 활동이 부분적으로 표시되지만 사용자 포커스가 없는 한 가지 경우를 살펴봅니다.
DessertClicker 앱을 실행한 상태에서 화면 오른쪽 상단의 공유 버튼을 클릭합니다.
공유 activity는 화면 하단에 나타나지만 Activity는 여전히 상단 절반에 표시됩니다.
Logcat을 검사하고 onPause()만 호출되었음을 확인합니다.
이 사용 사례에서는 Activity가 여전히 부분적으로 표시되기 때문에 onStop()이 호출되지 않습니다. 그러나 Activity에는 사용자 포커스가 없으며 사용자는 Activity와 상호 작용할 수 없습니다. Foreground에 있는 "공유" Activity에는 사용자 포커스가 있습니다.
이 차이가 왜 중요한가요? 이전의 계산 집약적인 앱을 고려하십시오. 앱이 Background에 있을 때 중지되지만 앱이 부분적으로 가려지면 계속 실행되기를 원할 수 있습니다. 이 경우 onStop()에서 종료합니다. Activity가 부분적으로 가려질 때 앱도 중지되도록 하려면 onPause()에 앱을 종료하는 코드를 삽입합니다.
onPause()에서 실행되는 코드는 다른 것이 표시되지 않도록 차단하므로 onPause()의 코드를 가볍게 유지하십시오. 예를 들어 전화가 오면 onPause()의 코드가 전화 수신 알림을 지연시킬 수 있습니다.
앱으로 돌아가려면 공유 대화 상자 외부를 클릭하고 onResume()이 호출된 것을 확인합니다.
onResume() 및 onPause() 모두 포커스와 관련이 있습니다. onResume() 메서드는 액티비티에 포커스가 있을 때 호출되고 onPause()는 액티비티가 포커스를 잃으면 호출됩니다.
Android 프래그먼트 수명 주기는 Activity 수명 주기와 유사하며 여러 프래그먼트별 메서드가 있습니다.
이 작업에서는 이전 코드랩에서 빌드한 AndroidTrivia 앱을 살펴보고 일부 로깅을 추가하여 Fragment 수명 주기를 탐색합니다.
AndroidTrivia 앱의 각 화면은 Fragment입니다.
작업을 단순하게 유지하기 위해 이 작업에서 Timber 라이브러리가 아닌 Android 로깅 API를 사용합니다.
이전 Codelab 중 하나에서 AndroidTriviaNavigation 앱을 열거나 GitHub에서 AndroidTriviaNavigation 솔루션 코드를 다운로드합니다.
TitleFragment.kt 파일을 엽니다. Android Studio는 앱을 다시 빌드할 때까지 바인딩 오류 및 해결되지 않은 참조 오류를 표시할 수 있습니다.
onCreateView() 메서드까지 아래로 스크롤합니다. 여기에서 Fragment의 레이아웃이 확장되고(inflate) 데이터 바인딩이 발생합니다.
setHasOptionsMenu() 행과 return에 대한 최종 호출 사이에 onCreateView() 메서드에 로깅 문을 추가합니다.
setHasOptionsMenu(true)
Log.i("TitleFragment", "onCreateView called")
return binding.root
override fun onAttach(context: Context) {
super.onAttach(context)
Log.i("TitleFragment", "onAttach called")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.i("TitleFragment", "onCreate called")
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Log.i("TitleFragment", "onViewCreated called")
}
override fun onStart() {
super.onStart()
Log.i("TitleFragment", "onStart called")
}
override fun onResume() {
super.onResume()
Log.i("TitleFragment", "onResume called")
}
override fun onPause() {
super.onPause()
Log.i("TitleFragment", "onPause called")
}
override fun onStop() {
super.onStop()
Log.i("TitleFragment", "onStop called")
}
override fun onDestroyView() {
super.onDestroyView()
Log.i("TitleFragment", "onDestroyView called")
}
override fun onDetach() {
super.onDetach()
Log.i("TitleFragment", "onDetach called")
}
앱을 컴파일 및 실행하고 Logcat을 엽니다.
검색 필드에 I/TitleFragment를 입력하여 로그를 필터링합니다. 앱이 시작되면 Logcat은 다음과 같이 보일 것입니다.
21933-21933/com.example.android.navigation I/TitleFragment: onAttach called
21933-21933/com.example.android.navigation I/TitleFragment: onCreate called
21933-21933/com.example.android.navigation I/TitleFragment: onCreateView called
21933-21933/com.example.android.navigation I/TitleFragment: onViewCreated called
21933-21933/com.example.android.navigation I/TitleFragment: onStart called
21933-21933/com.example.android.navigation I/TitleFragment: onResume called
Fragment의 전체 시작 수명 주기를 볼 수 있습니다.
onAttach(): 프래그먼트가 소유자 Activity과 연결될 때 호출됩니다.
onCreate(): 액티비티에 대한 onCreate()와 유사하게, 프래그먼트에 대한 onCreate()는 초기 프래그먼트 생성(레이아웃 제외)을 수행하기 위해 호출됩니다.
onCreateView(): 프래그먼트의 레이아웃을 확장하기 위해 호출됩니다.
onViewCreated(): onCreateView()가 반환된 직후에 호출되지만 저장된 상태가 뷰에 복원되기 전에 호출됩니다.
onStart(): Fragment가 화면에 표시될 때 호출됩니다. Activity의 onStart()와 병행합니다.
onResume(): 프래그먼트가 사용자 포커스를 얻을 때 호출됩니다. Activity의 onResume()과 병행합니다.
21933-21933/com.example.android.navigation I/TitleFragment: onPause called
21933-21933/com.example.android.navigation I/TitleFragment: onStop called
21933-21933/com.example.android.navigation I/TitleFragment: onDestroyView called
다음 Fragment를 열면 TitleFragment가 닫히고 다음과 같은 수명 주기 메서드가 호출됩니다.
onPause(): 프래그먼트가 사용자 포커스를 잃을 때 호출됩니다. Activity의 onPause()와 병행합니다.
onStop(): 프래그먼트가 더 이상 화면에 표시되지 않을 때 호출됩니다. 활동의 onStop()과 병행합니다.
onDestroyView(): 프래그먼트의 View가 더 이상 필요하지 않을 때 호출되어 해당 View와 관련된 리소스를 정리합니다.
앱에서 위로 버튼(화면의 왼쪽 상단 모서리에 있는 화살표)을 탭하여 제목 부분으로 돌아갑니다.
12422-12422/com.example.android.navigation I/TitleFragment: onCreateView called
12422-12422/com.example.android.navigation I/TitleFragment: onViewCreated called
12422-12422/com.example.android.navigation I/TitleFragment: onStart called
12422-12422/com.example.android.navigation I/TitleFragment: onResume called
이번에는 onAttach() 및 onCreate()가 프래그먼트를 시작하기 위해 호출되지 않을 수 있습니다. 프래그먼트 객체는 여전히 존재하고 여전히 소유자 Activity에 연결되어 있으므로 수명 주기는 onCreateView()로 다시 시작됩니다.
기기의 홈 버튼을 누릅니다. Logcat에서 onPause() 및 onStop()만 호출됩니다. 이것은 Activity의 경우와 동일한 동작입니다. 홈으로 돌아가면 Activity과 프래그먼트가 Background에 놓입니다.
최근 화면을 사용하여 앱으로 돌아갑니다. 액티비티에서 발생한 것처럼 onStart() 및 onResume() 메서드가 호출되어 프래그먼트을 Foreground으로 반환합니다.