Android에서 Fragment 전환하기: replace() 메서드의 비효율성 해결

Android 애플리케이션에서 Fragment 전환을 구현할 때 많은 개발자들이 replace() 메서드를 사용한다. 하지만 이 방식에는 심각한 성능 문제가 있다. 매번 전환할 때마다 Fragment가 새로 인스턴스화되고 데이터가 다시 로드되기 때문에, 성능과 사용자 데이터 사용량 측면에서 비효율적이다.

replace() 메서드의 문제점

Android 공식 문서에 따르면, replace() 메서드는 더 이상 필요 없는 Fragment를 교체할 때만 사용하는 것이 바람직하다.、日常적인 Fragment 전환에는 적합하지 않은 방식이다.

올바른 전환 방법: add(), hide(), show() 활용

효율적인 Fragment 전환을 위해서는 다음 패턴을 사용해야 한다:

  • 초기 Fragment 추가 시 add() 사용
  • 다른 Fragment로 전환 시 현재 Fragment는 hide(), 새 Fragment는 add()
  • 이미 추가된 Fragment 간 전환 시 hide()show()만 사용

이렇게 하면 여러 Fragment를 전환할 때마다 다시 인스턴스화하지 않아도 된다.

/**
 * Fragment 전환 관리자
 * 
 * @param current 현재 표시 중인 Fragment
 * @param target  전환할 목표 Fragment
 * @param containerId ViewGroup 컨테이너 ID
 */
public void switchFragment(Fragment current, Fragment target, int containerId) {
    if (activeFragment != target) {
        activeFragment = target;
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        
        if (!target.isAdded()) {
            transaction.hide(current)
                    .add(containerId, target, target.getClass().getSimpleName())
                    .commit();
        } else {
            transaction.hide(current).show(target).commit();
        }
    }
}

메모리 부족 시 발생하는 Fragment 중복 문제

위와 같이 구현하면 성능 문제는 해결되지만, 저사양 기기에서 메모리 부족으로 Activity가 재생성될 때 Fragment가 중복해서 표시되는 문제가 발생할 수 있다. 이는 Activity가回收되어 다시 시작될 때 Fragment가 중복으로 생성되기 때문이다.

savedInstanceState 검증을 통한 문제 해결

Activity의 onCreate() 메서드에서 savedInstanceState 여부를 반드시 확인해야 한다. 이 값을 검사함으로써 시스템이 Activity를 재구축하는 경우인지, 처음 시작하는 경우인지 구분할 수 있다.

Fragment를 찾을 때는 tag 파라미터가 필수적이다. 하나의 ViewGroup에 여러 Fragment가 추가될 수 있으므로, 각 Fragment를 고유하게 식별하기 위해 tag를 사용해야 한다.

/**
 * Activity 상태 복원 검증
 * 메모리 부족 상황에서 Fragment 중복 방지
 * 
 * @param savedInstanceState 번들 상태
 */
private void restoreFragmentState(Bundle savedInstanceState) {
    if (savedInstanceState == null) {
        fragmentManager = getFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        
        HomeFragment home = new HomeFragment();
        activeFragment = home;
        transaction.add(R.id.fragment_container, home, TAG_HOME);
        transaction.commit();
    } else {
        HomeFragment home = (HomeFragment) fragmentManager
                .findFragmentByTag(TAG_HOME);
        ProfileFragment profile = (ProfileFragment) fragmentManager
                .findFragmentByTag(TAG_PROFILE);
        SettingsFragment settings = (SettingsFragment) fragmentManager
                .findFragmentByTag(TAG_SETTINGS);
        
        fragmentManager.beginTransaction()
                .show(home)
                .hide(profile)
                .hide(settings)
                .commit();
        
        activeFragment = home;
    }
}

핵심 정리

Fragment 전환 시 반드시 기억해야 할 점은 다음과 같다:

  1. replace() 대신 add(), hide(), show() 조합 사용
  2. Fragment 추가 시 고유한 tag 지정
  3. Activity onCreate()에서 savedInstanceState null 검사 수행
  4. Activity 재구축 시 기존 Fragment를 tag로 찾아서 상태 복원

이 방법들을 적용하면 Fragment 전환 성능을 크게 개선하면서도 시스템 메모리 관리에 따른 중복 표시 문제를 원천적으로 방지할 수 있다.

태그: Android Fragment fragment-transaction android-development memory-management

7월 24일 00:23에 게시됨