Caused by: java.lang.IllegalStateException: Fragment already active at android.app.Fragment.setArguments(Fragment.java:696) ...
위와 같은 에러가 난다면 setArguments()의 주석을 먼저 확인해보자.
/** * Supply the construction arguments for this fragment. This can only * be called before the fragment has been attached to its activity; that * is, you should call it immediately after constructing the fragment. The * arguments supplied here will be retained across fragment destroy and * creation. */ public void setArguments(Bundle args) { if (mIndex >= 0) { throw new IllegalStateException("Fragment already active"); } mArguments = args; }
프래그먼트를 위한 생성자 아규먼트를 제공하며, 이 프래그먼트가 액티비티에 붙기(attach)전에만 호출된다고 한다. 그러므로, 프래그먼트를 만들자 마자 호출해야 제대로 동작한다는 뜻이다.
그럼, 저 에러를 나는 부분의 코드를 살펴보자. 보통 프래그먼트를 만든 후에 1회 이상 액티비티에 붙인 후일 것이다. 그러므로, setArgument()를 호출하면 이 프래그먼트는 이미 활성화(active)되어있다며 에러가 뜨게된다.
위 소스를 보면 mIndex라는 값이 0과 같거나 큰 경우에 에러를 던지고 있으며, 저 값은 Fragment.initState() 안에서 -1(최초 기본값)로 초기화 된다. 그리고, initState()는 프래그먼트가 remove 된 경우에만 프래그먼트 매니저에 의해 호출된다. 아래를 참고하자.
/** * Called by the fragment manager once this fragment has been removed, * so that we don't have any left-over state if the application decides * to re-use the instance. This only clears state that the framework * internally manages, not things the application sets. */ void initState() { mIndex = -1; mWho = null; mAdded = false; mRemoving = false; mResumed = false; mFromLayout = false; mInLayout = false; mRestored = false; mBackStackNesting = 0; mFragmentManager = null; mActivity = null; mFragmentId = 0; mContainerId = 0; mTag = null; mHidden = false; mDetached = false; mRetaining = false; mLoaderManager = null; mLoadersStarted = false; mCheckedForLoaderManager = false; }
그러므로, 프래그먼트 매니저를 통해 프래그먼트를 remove 해준 후, 다시 사용할 때 setArgument()를 제대로 호출할 수 있다. 예를 들면, remove() 호출방법은 아래와 같다.
getFragmentManager().beginTransaction().remove(activeFragment).commit();