[안드로이드] Activity와 Fragment (+ Kotlin Fragment 생명주기 예제코드)
Android에는 Activity와 Fragment가 있습니다.
Activity는 Android 4대 컴포넌트 중 하나이고, Fragment는 Activity내에서 작동하는 서브 컴포넌트입니다.
위의 화면을 보시면 Activity내에 Fragment 화면을 통해 UI를 구성한 것을 보실 수 있습니다.
Activity와 Fragment의 차이점입니다.
Activity | Fragment | |
독립성 | Android 앱의 기본 단위, 앱의 독립적인 화면을 담당 | Activity 내에서 작동하는 작은 모듈, 혼자서 존재할 수 없음 |
UI 관리 | 화면 전체를 관리 | Activity의 UI를 분할하는 데 사용 |
수명주기 | onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy() |
onAttach(), onCreate(), onCreateView(), onViewCreated(), onStart(), onResume(), onPause(), onStop(), onDestroyView(), onDestroy(), onDetach() |
재사용성 | 재사용성이 떨어짐, 다른 화면을 표시할 때 완전히 교체 |
여러 Activity 간 재사용할 수 있는 컴포넌트 |
그렇다면 Fragment는 왜 사용해야 하는 걸까요 ?
1. 재사용성, 모듈화
Fragment를 사용하면 독립적이고 재사용 가능한 UI 컴포넌트로 설계할 수 있습니다.
여러 Activity에서 동일한 Fragment를 사용하여, 코드 중복을 줄이고 유지 보수를 용이하게 할 수 있습니다.
또, Fragment는 앱의 UI 로직을 작은 모듈로 나눌 수 있어서 각 모듈을 독립적으로 개발할 수 있습니다.
2. 동적 UI 변경
Fragment를 사용하면 런타임에 UI를 동적으로 변경할 수 있습니다. 특히 복잡한 네비게이션이나 상호작용이 필요한 앱에서 유용합니다.
FragmentManager를 사용하여 Fragment 트랜잭션을 관리할 수 있어, 사용자가 뒤로가기 버튼을 누를 때 이전의 Fragmet로 돌아갈 수 있습니다.
*FragmentManager : 앱 Fragment에서 Fragment를 추가, 삭제 또는 교체하고 백 스택에 추가하는 등의 작업을 실행하는 클래스
*동적으로 UI 변경 : 앱의 코드가 정적인 xml 레이아웃만 사용하는 것이 아니라, 런타임 중간에 필요에 따라 UI를 변경할 수 있음
3. 수명주기
Fragment는 Activity의 수명 주기에 종속되어 있어, Activity와 함께 생명 주기를 관리할 수 있습니다.
Fragment는 Activity가 생성, 시작, 중지될 때 함께 관리되며, 이를 통해 메모리 누수를 방지하고 리소스 관리를 쉽게 할 수 있습니다.
=> Fragment는 복잡한 UI를 효율적으로 관리하고, 다양한 화면 크기와 장치에서 일관된 사용자 경험을 제공할 수 있습니다.
Fragment의 생명주기입니다.
예제 코드로 알아봅시다 !
import android.content.Context
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
class MyFragment : Fragment() {
private val TAG : String = "Fragment Lifecycle"
// Fragment가 Activity에 연결될 때 호출됩니다.
override fun onAttach(context: Context) {
super.onAttach(context)
Log.d(TAG, "onAttach called")
}
// Fragment가 생성될 때 호출됩니다. 비UI 로직 초기화에 적합합니다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "onCreate called")
}
// Fragment의 UI를 생성하기 위해 호출됩니다.
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
Log.d(TAG, "onCreateView called")
return inflater.inflate(R.layout.fragment_my, container, false)
}
// deprecated in API level 28. onActivityCreated -> onCreate()
// https://android-review.googlesource.com/c/platform/frameworks/support/+/1189651
// override fun onActivityCreated(savedInstanceState: Bundle?) {
// super.onActivityCreated(savedInstanceState)
// Log.d(TAG, "onActivityCreated called")
// }
// Fragment의 뷰가 생성된 후 호출됩니다. UI 초기화 작업에 적합합니다.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Log.d(TAG, "onViewCreated called")
}
// Fragment가 화면에 표시될 준비가 되었을 때 호출됩니다.
override fun onStart() {
super.onStart()
Log.d(TAG, "onStart called")
}
// Fragment가 사용자와 상호작용할 준비가 되었을 때 호출됩니다.
override fun onResume() {
super.onResume()
Log.d(TAG, "onResume called")
}
// Fragment가 사용자와의 상호작용을 중단할 때 호출됩니다.
override fun onPause() {
super.onPause()
Log.d(TAG, "onPause called")
}
// Fragment가 더 이상 화면에 표시되지 않을 때 호출됩니다.
override fun onStop() {
super.onStop()
Log.d(TAG, "onStop called")
}
// Fragment의 뷰 리소스를 해제할 때 호출됩니다.
override fun onDestroyView() {
super.onDestroyView()
Log.d(TAG, "onDestroyView called")
}
// Fragment가 완전히 소멸될 때 호출됩니다.
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "onDestroy called")
}
// Fragment가 Activity에서 분리될 때 호출됩니다.
override fun onDetach() {
super.onDetach()
Log.d(TAG, "onDetach called")
}
}
Activity에서 Fragment를 실행하면
onAttach() -> onCreate() -> onCreateView() -> onViewCreated -> onStart() -> onResume 순서대로 실행됩니다.
Fragment가 Activity에서 FragmentManager에 의해 추가되면 onAttach() 메서드가 호출된 상태입니다.
* onAttach()는 오버라이드하지 않아도 Fragment를 동작할 수 있지만, Activity Context에 접근하려면 onAttach()에서 처리하는 것이 좋습니다.
앱을 종료하면
onPause() -> onStop() -> onDestroyView() -> onDestroy() -> onDetach() 되어 종료됩니다.
onDetach는 FragmentManger에서 삭제되었을 때 분리되며 호출됩니다.
참고
https://developer.android.com/guide/fragments?hl=ko