development

예외 있음 : 조각이 이미 활성화 됨

big-blog 2020. 12. 10. 20:52
반응형

예외 있음 : 조각이 이미 활성화 됨


나는이 조각을 ;

MyFragment myFrag = new MyFragment();

이 조각 번들 데이터넣습니다 .

Bundle bundle = new Bundle(); 
bundle.putString("TEST", "test");
myFrag.setArguments(bundle);

그런 다음 이전 조각을이 조각으로 교체 하고 백 스택을 사용합니다 .

//replace old fragment
fragmentTransaction.replace(R.id.fragment_placeholder, myFrag, "MyTag");
//put on backstack
fragmentTransaction.addToBackStack(null);
//commit & get transaction ID
int transId = fragmentTransaction.commit();

나중에 위의 트랜잭션 ID ( )로 백 스택팝니다transId .

//pop the transaction from backstack
fragmentManager.popBackStack(transId,FragmentManager.POP_BACK_STACK_INCLUSIVE); 

나중에 번들 데이터 를 다시 내 fragment ( myFrag)에 인수로 설정 합니다 .

//Got Java.lang.IllegalStateException: fragment already active
myFrag.setArguments(bundle);

보시다시피 위의 코드에는 예외가 Java.lang.IllegalStateException: fragment already active있습니다. 백 스택에서 트랜잭션을 가져 왔지만 myFrag 여전히 활성 상태 인지 이해하지 못합니다 . , 어쨌든 예외가 발생했기 때문에 조각을 비활성화 할 수밖에 없다고 생각했기 때문에 다음과 같이했습니다.

Fragment activeFragment = fragMgr.findFragmentByTag("MyTag");
fragmentTransaction.remove(activeFragment);

프래그먼트를 비활성화하는 방법을 찾지 못했기 때문에 위 코드가 실제로 프래그먼트를 비활성화 할 수 있는지 확실 하지 않습니다. :(

그 후 번들 데이터를 myFrag다시 조각에 설정하려고하면 여전히 동일한 오류가 발생합니다.

Java.lang.IllegalStateException: fragment already active

조각을 제거한 것 같지만 여전히 활성화되어 있습니다 ... 왜? 조각을 비활성화하는 방법은 무엇입니까?


setArguments (Bundle args) 소스를 읽으면 다음 을 이해하는 데 도움이됩니다.

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

동일한 Fragment 의 코드에서 setArguments (Bundle args)를 다시 사용할 수 없습니다 . 당신이하고 싶은 것은 새로운 조각을 만들고 인수를 다시 설정하는 것입니다. 또는 getArguments () 를 사용한 다음 번들 메서드 를 사용하여 값을 변경할 수 있습니다. put


새 조각을 추가하기 전에 이전 조각을 제거해보십시오. https://stackoverflow.com/a/6266144/969325


remove () 조각 상태를 비활성화로 변경합니다. 귀하의 경우에는 remove (..) 후에 commit ()을 호출하지 않았습니다.

fragmentTransaction.remove(activeFragment);

remove () 후에도 commit ()을 수행합니다.

fragmentTransaction.remove(activeFragment).commit();

같은 문제가있었습니다. 조각을 백 스택에 추가했습니다. 그리고 오류는 popbackstack ()을 호출하지 않았기 때문입니다. popbackstack을 사용하면 도움이되었습니다.


I'm running into the same issue on Xamarin.android. Here's what the documentation says.

This can only be called before the fragment has been attached to its activity


Just call public method from fragment

if(userFragment==null){
                    userFragment = new UserFragment();
                    Bundle bundle = new Bundle();
                    bundle.putString(Constants.EXTRA_CUSTOMER, result);
                    userFragment.setArguments(bundle);
                }else{
                    try {
                        Customer customer = new Customer();
                        customer.parseCustomer(new JSONObject(result));
                        userFragment.updateVeiw(customer);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

First I start with describing why this happens and then I'll come up with the solution I found working... .

This issue happens when Android is removing the fragment from the stack but is not yet finished with removing. In order to check this, you can use the isRemoving() method of the fragment. If false, i.e. the fragment is not active, you can go on with setting the arguments using setArguments(bundle). Otherwise, you can't set arguments to an already active fragment and can only override it by addressing the same arguments using getArguments().putAll(bundle).

To summarize,

    if (myFrag.isRemoving()) {
        myFrag.getArguments().putAll(bundle);
    } else {
        myFrag.setArguments(bundle);
    }

If you want to avoid this, i.e. removing the fragment at once so there is no active fragment, you might want to use onBackPressed() in onBackStackChangedListener(), which will set the isRemoving() to false.


  1. Check whether your layout current one or old one for example

    setContentView(R.layout.activity_main);
    
  2. Delete old .gradle file in your project file and rebuild gradle file for project.

참고URL : https://stackoverflow.com/questions/10364478/got-exception-fragment-already-active

반응형