Fragment에서의 getContext()와 requireContext(), getActivity()와 requireActivity()

홍성덕·2024년 8월 1일

1. getContext()와 requireContext()

    /**
     * Return the {@link Context} this fragment is currently associated with.
     *
     * @see #requireContext()
     */
    @Nullable
    public Context getContext() {
        return mHost == null ? null : mHost.getContext();
    }

    /**
     * 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;
    }

requireContext()는 내부적으로 getContext()를 호출하여 getContext()의 리턴값이 null이면 IllegalStateException을 발생시킨다.

getContext()requireContext()의 주석 설명은 둘다 똑같다. 해석해보면 이 프래그먼트(함수를 호출한 프래그먼트)와 현재 연결된 Context를 리턴한다는 것이다. 단지 requireContext()는 리턴하는 Context가 null이 아니라고 가정할 뿐이다. 그래서 kt파일에서 함수를 각각 호출하면,getContext()Context?를 리턴하고 requireContext()Context를 리턴한다.


2. getActivity()와 requireActivity()

    /**
     * Return the {@link FragmentActivity} this fragment is currently associated with.
     * May return {@code null} if the fragment is associated with a {@link Context}
     * instead.
     *
     * @see #requireActivity()
     */
    @Nullable
    final public FragmentActivity getActivity() {
        return mHost == null ? null : (FragmentActivity) mHost.getActivity();
    }

    /**
     * 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;
    }

getActivity()requireActivity()도 비슷하다. requireActivity()에서 getActivity()를 호출하고 null이면 IllegalStateException을 발생시킨다. 주석 설명도 비슷한데, 이 프래그먼트(함수를 호출한 프래그먼트)와 현재 연결된 FragmentActivity를 리턴한다는 것이다.

getActivity()의 설명에는 만약 프래그먼트가 액티비티가 아닌 Context와 연결되어 있으면 null을 리턴한다고 한다. 내 생각에 이건 프래그먼트가 액티비티에 Attach 되어 있지 않은 상황을 말하는 것 같다. 어쨌든 호스트가 없다면 null을 리턴한다는 의미다.


3. requireContext(), requireActivity() 꼭 써야 할까?

내부적으로 살펴봤는데 requireContext(), requireActivity()가 Exception을 캐칭하는 것이 아니다. 물론 우리가 프래그먼트에서 작성하는 코드는, 보통 이미 Fragment가 호스트에 attach되어있는 상태에서 작동하는 코드로 작성하기 때문에, context가 null이 될 가능성은 실질적으로 없을 것이다.

그래도 어쨌든 Context가 nullable한 것은 변함이 없기 때문에 getContext(), getActivity()를 null 체크를 하고 사용하는 것이 더 안전하다고 볼 수 있다.


4. 언제 getContext()를 사용하고 언제 getActivity()를 사용해야 할까?

사실 대부분의 상황에서는 그냥 getContext()를 사용하는 것이 좋다. FragmentActivity는 Context의 하위 클래스인데 액티비티만의 변수와 메서드가 더 많이 포함되어 있기 때문에, 보다 가벼운 Context 객체를 사용하는 것이 더 효율적이다.

하지만 getActivity()를 사용해야 하는 때도 존재한다.
프래그먼트에서 호스트 액티비티의 메소드를 호출해야 할때, 액티비티의 자원을 가져와야 할 때, 액티비티와 프래그먼트가 서로 데이터를 주고받아야 할때, 프래그먼트에서 발생한 이벤트를 액티비티로 전달할 때 등이 있다.

예시로 프래그먼트에서 발생한 이벤트를 액티비티로 전달할 때의 코드를 작성해봤다.

	// 프래그먼트에서 버튼 클릭 이벤트 처리
	button.setOnClickListener {
        activity?.let { activity ->
            if (activity is MainActivity) {
                activity.onButtonClicked()
            }
        }
	}

// MainActivity의 메서드
fun onButtonClicked() {
    // 버튼 클릭 이벤트를 처리하는 코드
}
profile
안드로이드 주니어 개발자

0개의 댓글