본문 바로가기

개발 노트/Kotlin

[Android] Fragment Lifecycle

프래그먼트를 사용하면 화면하나를, 독립적으로 작동하는 부분화면 여러개로 구현할 수 있다

프레그먼트는 엑티비티처럼 레이아웃을 표시하고, 생명주기를 가지며 입력 이벤트를 받을 수 있다

하지만 독립적으로는 존재할 수 없고, 해당 프래그먼트를 관리하는 호스트 액티비티프래그먼트 하위에서만 존재할 수 있다

 

엑티비티는 안드로이드 4대 컴포넌트 중 하나로 안드로이드 시스템에서 관리하지만,

프레그먼트는 안드로이드 시스템이 직접 관리하지 않고 FragmentManager가 관리하기 때문에 엑티비티보다 메모리 리소스가 상대적으로 덜 소모된다.

또한 한번 작성된 프레그먼트는 여러 액티비티에서 재사용이 가능하며, 따라서 UI 구현에 필요한 작업량을 감소시킬 수 있다

 

 

# 프래그먼트 수명 주기 상태 및 콜백

 

 

-> 그림을 보면 Fragment Lifecycle 과 View Lifecycle이 상이한 것을 볼 수 있다.

Fragment의 Lifecycle이 변화되는 순간 Fragment Callback 함수를 호출하게 되고, 해당 콜백 함수가 종료되는 시점View의 Lifecycle 에 이벤트를 전달하게 된다

 

 

# onAttach() & onCreate()

Fragment CREATED

 

onAttach()
프래그먼트가 호스트 액티비티에 attach 된다

 

onCreate()
프래그먼트 자체가 생성된다

 

-> CREATED 상태에 있을 때, 프래그먼트는 FragmentManager에 추가되며 onAttach() onCreate()가 차례대로 호출된다

onAttach()에서는 프래그먼트가 호스트 액티비티에 attach 되고, onAttach()에서 작업이 성공적으로 이루어지면 onCreate()에서 프래그먼트 자체가 생성된다. 이때 프래그먼트 뷰는 아직 생성되지 않은 상태이므로, 뷰와 관련된 작업을 onCreate() 내부에 하는 것은 적절하지 않다.

 

 

 

# onCreateView() & onViewCreated()

Fragment CREATED & View INITIALIZED

 

onCreateView()
프래그먼트 뷰가 초기화되며, 정상적으로 초기화가 되었다면 뷰 객체를 반환한다

 

onViewCreated()
onCreateView()에서 뷰 객체가 반환된 직후에 호출되며, 뷰가 완전히 생성되었음을 보장한다

 

-> onCreate() 이후에는 onCreateView() 와 onViewCreated() 콜백함수가 이어서 호출됩니다. onCreateView() 의 반환값으로 정상적인 Fragment View 객체를 제공했을 때만 Fragment View 의 Lifecycle 이 생성된다

이때 레이아웃을 inflate 하기 때문에 findViewById() 또는 View Binding을 사용해서 다른 뷰들을 참조할 수도 있지만, 종종 레이아웃이 제대로 초기화가 되지 않을 수도 있다. 그렇기때문에 뷰에 대한 참조 및 작업은 뷰가 완전히 생성된 이후인 onViewCreated()에서 하는 것이 더 안전하다

 

class MainFragment : Fragment(){ 

    private lateinit var binding : FragmentMainBinding
    private val viewModel : ViewModel by inject()

   	override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentMainBinding.inflate(inflater)        
        return binding.root
    }
    
    override fun onViewCreated(view: View, savedInstance: Bundle?){
    	super.onViewCreated(view, savedIntanceState)
    
    	binding.btn.setOnClickListener {
        	...
        }
        
        viewModel.getAll().observe(viewLifecycleOwner, Observer{
        	...
        })
        
    }
}

 

 

 

# onViewStateRestored()

Fragment & View CREATED

 

onViewStateRestored()은 저장해둔 모든 state 값이  Fragment 의 View의 계층구조에 복원되었을 때 호출된다.

따라서 여기서부터는 체크박스 위젯이 현재 체크 되어있는지 등 각 뷰의 상태값을 체크할 수 있습니다.

 

 

# onStart()

Fragment & View STARTED

 

Fragment 가 사용자에게 보여질 수 있을 때 호출된다

childFragmentManager를 통해 FragmentTransaction을 안전하게 수행할 수 있다.

 

 

# onResume()

Fragment & View RESUMED

 

사용자와 프래그먼트가 상호작용 할 수 있는 상태로,

프래그먼트가 보이는 상태에서 모든 Animator와 Transition 효과가 종료된 후 호출된다.

 

 

# onPause()

Fragment & View STARTED

 

사용자가 프래그먼트를 떠났지만 기존 프래그먼트가 조금이라도 보일 때 호출된다.

(Fragment 는 여전히 visible 일 때 onPause()가 호출)

이 때 프래그먼트와 프래그먼트 뷰의 생명주기는 PAUSED가 아닌 STARTED 상태가 된다.

엄밀히 따지면 Lifecycle 에 PAUSE 와 STOP 에 해당하는 상태가 없는 상태다

 

 

# onStop()

Fragment & View CREATED

 

프래그먼트가 더이상 보이지 않을 때 호출된다.

onStop()은 호스트 액티비티나 프래그먼트가 중단되었을 뿐만 아니라, 부모 액티비티나 프래그먼트의 상태가 저장될 때도 호출된다

주의해야할 점이 있는데, API 레벨 28 이후 onSaveInstanceState()와 onStop() 호출 순서가 달라졌고, 따라서 onStop()이 FragmentTransaction을 안전하게 수행하는 마지막 지점이 되었다.

 

 

# onDestroyView()

Fragment CREATED & View DESTROYED

 

프래그먼트의 뷰가 소멸될 시 호출된다

이때 프래그먼트 자체는 아직 메모리에 남아있으므로, 프래그먼트 뷰에 대한 모든 참조를 제거해야 메모리 누수를 방지할 수 있다. 따라서 만약 View Binding을 사용하고 있다면 onDestroyView()에서 binding 변수를 null로 만들어 주는 것이 좋다

 

override fun onDestroyView() {
	super.onDestroyView()
    binding = null
}

 

 

 

# onDestroy()

Fragment DESTROYED

 

프래그먼트 또는 프래그먼트 매니저가 소멸되었을 경우 호출되며,

onDestroy()가 호출되었다는 것은 프래그먼트의 생명주기도 종료되었다는 것을 의미한다.

 

 

 

 

 

 

 

# 참고한 공식문서와 자료

https://developer.android.com/guide/fragments/lifecycle?hl=ko

 

프래그먼트 수명 주기  |  Android 개발자  |  Android Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 프래그먼트 수명 주기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 각 Fragment 인스턴스에는 고유한

developer.android.com

 

https://readystory.tistory.com/199

 

[Android] 의외로 잘 모르는 Fragment 의 Lifecycle

많은 앱들이 여러가지 이유로 single activity application 을 지향하고 있습니다. 따라서 Fragment 로 UI 를 구성하는 경우가 굉장히 많은데요. 이때 많은 개발자들이 Activity 의 Lifecycle 에 대해서는 잘 알고

readystory.tistory.com

 

https://velog.io/@jeongminji4490/Android-Fragment-Lifecycle

 

[Android] Fragment Lifecycle

안드로이드에 처음 입문했을 때는 잘 몰라서 무작정 액티비티만 만들었던 기억이 난다. 그래서 화면이 많아지면 많아질수록 액티비티 수도 그만큼 늘어났고, 액티비티가 좀 무겁기 때문에 빌드

velog.io