Fragment에서의 Activity와 Context의 구분
소개
Fragment에 있어서의
Activity
와 Context
의 의미나 구분을 모르기 때문에, 조사해 보았습니다.결론
Context
으로 끝난다this.context
requireContext()
Activity
를 건네줄 필요가 있다this.activity
requireActivity()
환경
조사
각 처리의 반환값
Fragment에서 다음을 수행했습니다.
MonsterListFragment.kt
Timber.d("${this.activity}")
Timber.d("${requireActivity()}")
Timber.d("${this.context}")
Timber.d("${requireContext()}")
Logcat의 출력 결과
2021-03-06 19:07:40.162 24680-24680/com.theuhooi.uhooipicbook D/MonsterListFragment: com.theuhooi.uhooipicbook.MainActivity@95e20bb
2021-03-06 19:07:40.162 24680-24680/com.theuhooi.uhooipicbook D/MonsterListFragment: com.theuhooi.uhooipicbook.MainActivity@95e20bb
2021-03-06 19:07:40.163 24680-24680/com.theuhooi.uhooipicbook D/MonsterListFragment: dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper@e47f888
2021-03-06 19:07:40.166 24680-24680/com.theuhooi.uhooipicbook D/MonsterListFragment: dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper@e47f888
this.activity
및 requireActivity()
, this.context
및 requireContext()
의 출력은 동일합니다.즉 동일한 인스턴스를 반환합니다.
require○○() vs this.○○
requireActivity()
와 requireContext()
의 구현을 살펴 보겠습니다.Fragment.java
/**
* Return the {@link FragmentActivity} this fragment is currently associated with.
*
* @throws IllegalStateException if not currently associated with an activity or if associated
* only with a context.
* @see #getActivity()
*/
@NonNull
public final FragmentActivity requireActivity() {
FragmentActivity activity = getActivity();
if (activity == null) {
throw new IllegalStateException("Fragment " + this + " not attached to an activity.");
}
return activity;
}
Fragment.java
/**
* Return the {@link Context} this fragment is currently associated with.
*
* @throws IllegalStateException if not currently associated with a context.
* @see #getContext()
*/
@NonNull
public final Context requireContext() {
Context context = getContext();
if (context == null) {
throw new IllegalStateException("Fragment " + this + " not attached to a context.");
}
return context;
}
보시다시피,
activity (context)
가 null
이면 예외가 발생하고 null
가 아니면 인스턴스를 반환하는 간단한 구현입니다.전달할 대상이
null
를 허용하는 경우 null
의 오류 처리를 맡길 수 있으므로 require○○()
를 호출하지 않고 this.○○
로 전달해야 한다고 생각합니다.require○○()
를 호출하면 예외가 발생해, 그 외로 핸들링할 수 없게 되기 때문입니다.반대로
null
가 아닌 context
나 activity
가 필요한데 require○○()
를 사용하지 않는 것은 중복이므로 피해야합니다.MonsterListFragment.kt
class MonsterListFragment : Fragment() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// ×冗長
this.context?.let {
MaterialAlertDialogBuilder(it)
}
// ○簡潔
MaterialAlertDialogBuilder(requireContext())
}
}
Activity vs Context
출력 결과와
require○○()
메서드의 구현에서 Fragment가 가지는 activity
의 형태는 FragmentActivity
, context
의 형태는 Context
라는 것을 알았습니다.FragmentActivity
의 상속을 따라가면 Context
에 도착합니다.Context
↑
ContextWrapper
↑
ContextThemeWrapper
↑
Activity
↑
androidx.core.app.ComponentActivity
↑
ComponentActivity
↑
FragmentActivity
가능한 한 작게 끝내고 싶기 때문에,
Context
로 끝나는 곳에 Activity
를 건네줄 필요는 없다고 생각합니다.Context 유형
FragmentActivity
의 상속도로부터 Activity
가 Context
의 자손인 것을 알았습니다.마찬가지로
Application
도 Context
의 자손임을 알 수 있습니다.Context
↑
ContextWrapper
↑
Application
Context를 구별하기 위해, Application를 「Application Context」, Activity를 「Activity Context」라고 부르는 경우가 있습니다.
Fragment에서 얻을 수 있는 Context는 「Activity Context」이며, 「Application Context」는 Activity를 개입하지 않으면 취득할 수 없습니다(잘못되어 있으면 지적해 주세요).
Activity
에서 this.applicationContext
에서 Application Context를 얻을 수 있습니다.Application Context 쪽이 생존 기간이 길기 때문에 안전합니다.
그러나 기본적으로는 Activity의 라이프 사이클에 따라 Activity Context를 사용하는 것이 좋을 것 같습니다.
검증되지 않았지만 Fragment의
this.activity
와 this.context
는 동일한 인스턴스 (이번에는 MainActivity
)를 참조하는 것으로 보입니다.즉 기본적으로 어느 것을 사용해도 변하지 않습니다.
this.activity
와 this.context
의 내용이 다르거나 한쪽만 null
가 되는 케이스가 있는지 궁금합니다.결론
본 기사의 내용은 어디까지나 내가 내놓은 결론입니다.
다른 의견이나 지적 등이 있으시면 언제든지 코멘트 등을 부탁드립니다.
참고 링크
Reference
이 문제에 관하여(Fragment에서의 Activity와 Context의 구분), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/uhooi/items/471b14cb74adadebc33c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)