본문 바로가기
AOS🤖/Common

[AOS] Activity 와 Fragment 의 차이

by 텅빈비니 2024. 3. 2.
반응형

안녕하세요🐶

빈지식 채우기의 비니🙋🏻‍♂️ 입니다.

 

오늘은 ActivityFragment 를 비교하는 시간을 가지겠습니다.

해당 포스팅은 Android 공식 문서를 바탕으로 작성하였습니다.


1. Acitivity

  • Android 앱에서 중요한 요소 중 하나이며, Activity가 시작되어 조합되는 방식은 어플리케이션 모델의 기본적인 부분입니다.
  • main() 메서드를 사용하여 앱을 실행하는 프로그래밍이다.
  • 수명 주기의 특정 단계에 상응하는 콜백 메서드를 호출하여 Acitivity 를 실행합니다.
  • 모바일 앱 환경은 테스트콥 앱 환경과 다른 특징을 가지고 있습니다.
    • 사용자와 앱이 보는 화면이 항상 동일한 위치에서 시작되는 것이 아닙니다.
    • 예를 들어, 특정 앱에서 어떠한 기능을 수행하기 위해 버튼을 우르면 해당 화면으로 바로 이동할 수 있습니다.
    • 앱이 다른 앱을 호출할 때 앱의 전체를 호출하는 것이 아니고, 특정 Acitivity 를 호출합니다.
  • Activity 는 앱이 UI를 그리는 창을 제공합니다.

 

1-1. Acitivity 선언

<manifest ... >
  <application ... >
      <activity android:name=".ExampleActivity" />
      ...
  </application ... >
  ...
</manifest >
  • 매니페스트 파일을 열고 위와 같이 application 태그의 하위 요소로 추가합니다.

 

1-2. 수명 주기

Activity 수명 주기

  1. onCreate()
    • 시스템에서 Acitivy를 생성할 때 실행됩니다.
    • 구현 시 필수 데이터를 초기화를 해야 합니다.
    • Activity 와 ViewModel 를 연결합니다.
    • savedInstanceState 라는 변수가 있는데, 이 매개변수는 Activity 이전 상태에 대한 정보가 저장되어 있습니다.
    • 이후에 항상 onStart() 가 호출됩니다.
  2. onStart()
    • Activity가 사용자에게 표시되는 단계입니다.
    • Activity가 포그라운드로 이동하여 상호작용이 되기 위한 최종 준비에 해당하는 작업이 포함되어 있습니다.
  3. onResume()
    • Activity가 포그라운드에서 사용자와 상호작용을 시작하기 직전에 호출합니다.
  4. onPause()
    • 사용자가 이 Activity를 잠시 떠나면 호출합니다.
    • onPause() 실행이 완료되고 다음 콜백은 활동이 일시중지됨 상태로 전환됩니다. 이후 발생하는 상황에 따라 onStop() 또는 onResume() 호출됩니다.
  5. onStop()
    • Activity가 더 이상 사용자에게 표시되지 않으면 시스템은 해당 콜백을 호출합니다.
    • 다음 호출은 onRestart()(활동이 사용자와 상호작용 하기 위해 돌아오는 경우) 또는 onDestory()(활동이 완전히 종료되는 경우)가 호출됩니다.
  6. onRestart()
    • 시스템이 중지된 상태에서 다시 시작될 때 해당 콜백을 호출합니다.
    • 다음 호출은 onStart()가 호출됩니다.
  7. onDestroy()
    • Activity가 완전히 소멸될 때 호출됩니다.
    • 프로세스가 소멸될 때, Activity의 리소스를 모두 해제되도록 구현합니다.

 

3-3. Activity의 통신

var intent = Intent(this, MyActivity::class.java).apply {
	putExtra("media_id", "a1b2c3")
    // ...
    }
  • Activity 간 통신을 할 때에는 Intent 객체를 사용합니다.
  • Bundle 객체를 생성하여 데이터를 담아 전달합니다.
    • 단 데이터의 크기는 너무 높지 않도록 주의 합니다. ( 오류가 발생할 수 있음 )

 

 


2. Fragment

Fragment UI

  • Fragment는 독립적으로 존재할 수 없습니다.
    • Acitivy 또는 Fragment 안에 반드시 포함되어 있어야 합니다.
    • 즉, Activity가 더 큰 범위라고 볼 수 있습니다.
  • 자체적으로 레이아웃을 정리하고 관리하며, 자체 수명주기를 보유하고 있습니다.
    • 자체적으로 입력 이벤트를 처리할 수 있습니다.
  • 다양한 화면 구성을 하기 위해 Activity UI에 모듈성과 재사용성을 보장합니다.
  • Fragment는 다양한 UI를 모듈화하여 재사용하고 화면 구성을 더욱 쉽게 하도록 도와주는 역할을 수행합니다.

 

2-1. 수명 주기

Fragment 수명 주기

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" 키 값으로 데이터를 저장합니다.

감사합니다.


참고

반응형