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();