728x90
반응형
안녕하세요🐶
빈지식 채우기의 비니🙋🏻♂️ 입니다.
오늘은 Activity 와 Fragment 를 비교하는 시간을 가지겠습니다.
해당 포스팅은 Android 공식 문서를 바탕으로 작성하였습니다.
1. Acitivity
- Android 앱에서 중요한 요소 중 하나이며, Activity가 시작되어 조합되는 방식은 어플리케이션 모델의 기본적인 부분입니다.
- main() 메서드를 사용하여 앱을 실행하는 프로그래밍이다.
- 수명 주기의 특정 단계에 상응하는 콜백 메서드를 호출하여 Acitivity 를 실행합니다.
- 모바일 앱 환경은 테스트콥 앱 환경과 다른 특징을 가지고 있습니다.
- 사용자와 앱이 보는 화면이 항상 동일한 위치에서 시작되는 것이 아닙니다.
- 예를 들어, 특정 앱에서 어떠한 기능을 수행하기 위해 버튼을 우르면 해당 화면으로 바로 이동할 수 있습니다.
- 앱이 다른 앱을 호출할 때 앱의 전체를 호출하는 것이 아니고, 특정 Acitivity 를 호출합니다.
- Activity 는 앱이 UI를 그리는 창을 제공합니다.
1-1. Acitivity 선언
<manifest ... >
<application ... >
<activity android:name=".ExampleActivity" />
...
</application ... >
...
</manifest >
- 매니페스트 파일을 열고 위와 같이 application 태그의 하위 요소로 추가합니다.
1-2. 수명 주기
- onCreate()
- 시스템에서 Acitivy를 생성할 때 실행됩니다.
- 구현 시 필수 데이터를 초기화를 해야 합니다.
- Activity 와 ViewModel 를 연결합니다.
- savedInstanceState 라는 변수가 있는데, 이 매개변수는 Activity 이전 상태에 대한 정보가 저장되어 있습니다.
- 이후에 항상 onStart() 가 호출됩니다.
- onStart()
- Activity가 사용자에게 표시되는 단계입니다.
- Activity가 포그라운드로 이동하여 상호작용이 되기 위한 최종 준비에 해당하는 작업이 포함되어 있습니다.
- onResume()
- Activity가 포그라운드에서 사용자와 상호작용을 시작하기 직전에 호출합니다.
- onPause()
- 사용자가 이 Activity를 잠시 떠나면 호출합니다.
- onPause() 실행이 완료되고 다음 콜백은 활동이 일시중지됨 상태로 전환됩니다. 이후 발생하는 상황에 따라 onStop() 또는 onResume() 호출됩니다.
- onStop()
- Activity가 더 이상 사용자에게 표시되지 않으면 시스템은 해당 콜백을 호출합니다.
- 다음 호출은 onRestart()(활동이 사용자와 상호작용 하기 위해 돌아오는 경우) 또는 onDestory()(활동이 완전히 종료되는 경우)가 호출됩니다.
- onRestart()
- 시스템이 중지된 상태에서 다시 시작될 때 해당 콜백을 호출합니다.
- 다음 호출은 onStart()가 호출됩니다.
- onDestroy()
- Activity가 완전히 소멸될 때 호출됩니다.
- 프로세스가 소멸될 때, Activity의 리소스를 모두 해제되도록 구현합니다.
3-3. Activity의 통신
var intent = Intent(this, MyActivity::class.java).apply {
putExtra("media_id", "a1b2c3")
// ...
}
- Activity 간 통신을 할 때에는 Intent 객체를 사용합니다.
- Bundle 객체를 생성하여 데이터를 담아 전달합니다.
- 단 데이터의 크기는 너무 높지 않도록 주의 합니다. ( 오류가 발생할 수 있음 )
2. Fragment
- Fragment는 독립적으로 존재할 수 없습니다.
- Acitivy 또는 Fragment 안에 반드시 포함되어 있어야 합니다.
- 즉, Activity가 더 큰 범위라고 볼 수 있습니다.
- 자체적으로 레이아웃을 정리하고 관리하며, 자체 수명주기를 보유하고 있습니다.
- 자체적으로 입력 이벤트를 처리할 수 있습니다.
- 다양한 화면 구성을 하기 위해 Activity UI에 모듈성과 재사용성을 보장합니다.
- Fragment는 다양한 UI를 모듈화하여 재사용하고 화면 구성을 더욱 쉽게 하도록 도와주는 역할을 수행합니다.
2-1. 수명 주기
A. 상향 상태 전환
1. CREATED
- Fragment가 CREATED 상태에 도달하면 이미 Fragment는 FramgentManager에 추가가 되고, onAttach() 메서드가 호출된 상태입니다.
- Fragement가 처음 생성될 때는 savedInstanceState가 null 값을 갖지만, 그렇지 않다면 재생성 되는 것입니다.
- 이 상태에서는 데이터를 초기화 또는 복구 그리고 저장된 상태를 불러옵니다.
2. STARTED
- Fragment 안에 View 들을 사용할 수 있는 상태가 됩니다.
3. RESUMED
- 사용자가 Fragment 와 상호작용 할 수 있음을 나타내는 단계입니다.
B. 하향 상태 전환
1. STARTED
- Fragment의 onPause() 를 호출하는 단계입니다.
- 사용자로부터 Fragment 의 포커스를 잃은 상태입니다.
2. CREATED
- 더 이상 Fragment 가 포그라운드에서 보이지 않는 상태입니다.
3. DESTORYED
- Fragment 안에 있는 View 들이 Detach 되고, Fragment 역시 FragmentManager에서 Detach 되는 단계입니다.
2-2. Fragment의 통신
프래그먼트 간 상태를 공유하려면, 프래그먼트 간의 통신이 필요합니다.
2-3-1. ViewModel을 이용한 통신
class ListViewModel : ViewModel() {
val filters = MutableLiveData<Set<Filter>>()
private val originalList: LiveData<List<Item>>() = ...
val filteredList: LiveData<List<Item>> = ...
fun addFilter(filter: Filter) { ... }
fun removeFilter(filter: Filter) { ... }
}
class ListFragment : Fragment() {
// Using the activityViewModels() Kotlin property delegate from the
// fragment-ktx artifact to retrieve the ViewModel in the activity scope.
private val viewModel: ListViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
viewModel.filteredList.observe(viewLifecycleOwner, Observer { list ->
// Update the list UI.
}
}
}
class FilterFragment : Fragment() {
private val viewModel: ListViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
viewModel.filters.observe(viewLifecycleOwner, Observer { set ->
// Update the selected filters UI.
}
}
fun onFilterSelected(filter: Filter) = viewModel.addFilter(filter)
fun onFilterDeselected(filter: Filter) = viewModel.removeFilter(filter)
}
- ListVIewModel 을 생성하고, 사용할 프로퍼티 및 함수를 정의합니다.
- 이후 ListViewModel을 사용하고자 하는 두개의 Fragment를 정의하고, 미리 생성한 ListViewModel을 공유합니다.
- 그 이후 Observe 를 통해 변경(업데이트) 된 정보를 공유받을 수 있습니다.
2-3-2. Fragment Result API를 이용한 통신
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Use the Kotlin extension in the fragment-ktx artifact.
setFragmentResultListener("requestKey") { requestKey, bundle ->
// We use a String here, but any type that can be put in a Bundle is supported.
val result = bundle.getString("bundleKey")
// Do something with the result.
}
}
- "requestKey" 로 들어오는 Result Listener을 정의합니다.
- "bundleKey" 키 값으로 저장된 데이터를 공유 받습니다.
button.setOnClickListener {
val result = "result"
// Use the Kotlin extension in the fragment-ktx artifact.
setFragmentResult("requestKey", bundleOf("bundleKey" to result))
}
- "requestKey" 키 값으로 정의된 Fregment Result 를 초기화 및 설정합니다.
- "bundleKey" 키 값으로 데이터를 저장합니다.
감사합니다.
참고
728x90
반응형