developer tip

ViewPager에서 탭을 사용할 때 "Java.lang.IllegalStateException 활동이 삭제되었습니다"오류가 발생 함

optionbox 2020. 8. 3. 08:29
반응형

ViewPager에서 탭을 사용할 때 "Java.lang.IllegalStateException 활동이 삭제되었습니다"오류가 발생 함


탭 모드에서 ActionBarSherlock을 사용하는 응용 프로그램이 있습니다 .5 개의 탭이 있으며 각 탭의 내용은 조각을 사용하여 처리됩니다. 그러나 tab2의 경우 xml 파일에 조각 페이지가있는 ViewPager 요소가있는 조각이 있습니다. 처음 응용 프로그램을 응용 프로그램을 시작하면 탭 사이에서 아무런 문제가 없지만 tab2를 두 번 누르면 위에서 언급 한 오류가 발생합니다. 주요 활동은 다음과 같습니다.

public class MainActivity extends SherlockFragmentActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ActionBar actionBar = getSupportActionBar();

        ActionBar.Tab tab1 = actionBar.newTab().setText("Tab1");
        ActionBar.Tab tab3 = actionBar.newTab().setText("Tab3");
        ActionBar.Tab tab2 = actionBar.newTab().setText("Tab2");
        ActionBar.Tab tab4 = actionBar.newTab().setText("Tab4");
        ActionBar.Tab tab5 = actionBar.newTab().setText("Tab5");

        Fragment fragment1 = new Tab1();
        Fragment fragment3 = new Tab3();
        Fragment fragment2 = new Tab2();
        Fragment fragment5 = new Tab5();
        Fragment fragment4 = new Tab4();

        tab1.setTabListener(new MyTabListener(fragment1));
        tab3.setTabListener(new MyTabListener(fragment3));
        tab2.setTabListener(new MyTabListener(fragment2));
        tab5.setTabListener(new MyTabListener(fragment5));
        tab4.setTabListener(new MyTabListener(fragment4));

        actionBar.addTab(tab1);
        actionBar.addTab(tab2);
        actionBar.addTab(tab3);
        actionBar.addTab(tab4);
        actionBar.addTab(tab5); 

        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    }

    class MyTabListener implements ActionBar.TabListener
    {
        Fragment fragment;

        public MyTabListener(Fragment fragment)
        {
            this.fragment = fragment;
        }

        @Override
        public void onTabSelected(com.actionbarsherlock.app.ActionBar.Tab tab,FragmentTransaction ft) 
        {
            ft.replace(R.id.fragment_container,fragment);
        }

        @Override
        public void onTabUnselected(com.actionbarsherlock.app.ActionBar.Tab tab,FragmentTransaction ft) 
        {

        }

        @Override
        public void onTabReselected(com.actionbarsherlock.app.ActionBar.Tab tab,FragmentTransaction ft) 
        {

        }
    }
}

ViewPager가없는 프래그먼트 클래스는 다음과 같습니다.

public class Tab1 extends Fragment 
{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
    {
        return inflater.inflate(R.layout.activity_tab1, container, false);
    }
}

ViewPager의 조각 클래스는 다음과 같습니다.

public class Tab2 extends Fragment 
{
    ViewPager mViewPager;
    private MyFragmentPagerAdapter mMyFragmentPagerAdapter;  
    private static int NUMBER_OF_PAGES = 5;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
    {
        View view =  inflater.inflate(R.layout.activity_tab2, container, false); 
        return view;
    }

    @Override
    public void onViewCreated(View view,Bundle savedInstanceState)
    {
        super.onViewCreated(view, savedInstanceState);
        mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
        mMyFragmentPagerAdapter = new MyFragmentPagerAdapter(getChildFragmentManager());  
        mViewPager.setAdapter(mMyFragmentPagerAdapter);  
    }

    private static class MyFragmentPagerAdapter extends FragmentPagerAdapter 
    {    
        public MyFragmentPagerAdapter(FragmentManager fm) 
        {  
             super(fm);  
        }  

        @Override  
        public Fragment getItem(int index) 
        {  
             return PageFragment.newInstance("My Message " + index);
        }  

        @Override  
        public int getCount() 
        {  
             return NUMBER_OF_PAGES;  
        }  
   }
}

다른 곳에서 읽은 것에서 (그리고 내가 틀렸다면 수정하십시오), 두 번째 단계의 조각 관리자는 더 이상 존재하지 않는 활동에서 조각을 재사용하려고 시도하므로 오류가 발생하기 때문에 발생합니다. 그러나 조각 활동을 사용하지 않기 때문에 왜 이것이 여기에서 발생하는지 잘 모르겠습니다. logcat에 따르면 오류는 Tab2 클래스, mViewPager.setAdapter (mMyFragmentPagerAdapter)라고 표시된 줄의 onViewCreated 메소드에 있습니다. 어떤 도움이라도 대단히 감사합니다 ... 감사합니다.

03-04 12:01:05.468: E/AndroidRuntime(2474): FATAL EXCEPTION: main
03-04 12:01:05.468: E/AndroidRuntime(2474): java.lang.IllegalStateException: Activity has been destroyed
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1342)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:578)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:139)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.support.v4.view.ViewPager.populate(ViewPager.java:1011)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.support.v4.view.ViewPager.populate(ViewPager.java:880)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:433)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at com.example.tabs.Tab2.onViewCreated(Tab2.java:31)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:925)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:429)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.os.Handler.handleCallback(Handler.java:587)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.os.Handler.dispatchMessage(Handler.java:92)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.os.Looper.loop(Looper.java:123)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at android.app.ActivityThread.main(ActivityThread.java:3687)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at java.lang.reflect.Method.invokeNative(Native Method)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at java.lang.reflect.Method.invoke(Method.java:507)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
03-04 12:01:05.468: E/AndroidRuntime(2474):     at dalvik.system.NativeStart.main(Native Method)

이것은 중첩 단편에 대한 새로 추가 된 지원에서 버그 인 것 같습니다. 기본적으로 자식 FragmentManager은 활동에서 분리 될 때 내부 상태가 깨집니다. 나를 위해 고친 단기 해결 방법은 전화 하는 onDetach()모든 것에 다음을 추가 Fragment하는 것 getChildFragmentManager()입니다.

@Override
public void onDetach() {
    super.onDetach();

    try {
        Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
        childFragmentManager.setAccessible(true);
        childFragmentManager.set(this, null);

    } catch (NoSuchFieldException e) {
        throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    }
}

I'm having exactly the same problem. The only workaround I've found, is to replace the fragments by a new instance, each time the tabs are changed.

ft.replace(R.id.fragment_container, Fragment.instantiate(PlayerMainActivity.this, fragment.getClass().getName()));

Not a real solution, but i haven't found a way to reuse the previous fragment instance...


I encountered the same issue when calling super.onCreate() at the end of my method. The reason: attachActivity() is called in onCreate() of FragmentActivity. When overriding onCreate() and, for example, creating tabs, the Tab manager will try to switch to a fragment while not having the activity attached to the FragmentManager.

Simple solution: Move the call to super.onCreate() to the head of the function body.

In general, it seems there are loads of reasons this issue may occur. This is just another one ...

Matthias


Wanted to add that my problem was in an activity where I tried to make a FragmentTransaction in onCreate BEFORE I called super.onCreate(). I just moved super.onCreate() to top of function and was worked fine.


I had this error because I was using LocalBroadcastManager and I did:

unregisterReceiver(intentReloadFragmentReceiver);

instead of:

LocalBroadcastManager.getInstance(this).unregisterReceiver(intentReloadFragmentReceiver);

I encountered the same issue and lateron found out that, I have missed call to super.onCreate( savedInstanceState ); in onCreate() of FragmentActivity.


I got the very same error when trying to access the child FragmentManager before the fragment was fully initialized (i.e. attached to the Activity or at least onCreateView() called). Else the FragmentManager gets initialized with a null Activity causing the aforementioned exception.


I force the fragment containing the child fragment to NULL in onPause and it fixes my problem

fragment = null;

I know this is an old post, but the suggested answers didn't work on my end. I want to leave this here just in case someone will find it useful.

What i did is:

@Override
public void onResume() {
    super.onResume();
    // add all fragments
    FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
    for(Fragment fragment : fragmentPages){
        String tag = fragment.getClass().getSimpleName();
        fragmentTransaction.add(R.id.contentPanel, fragment, tag);
        if(fragmentPages.indexOf(fragment) != currentPosition){
            fragmentTransaction.hide(fragment);
        } else {
            lastTag = tag;
        }
    }
    fragmentTransaction.commit();
}

Then in:

@Override
public void onPause() {
    super.onPause();
    // remove all attached fragments
    for(Fragment fragment: fragmentPages){
        getChildFragmentManager().beginTransaction().remove(fragment).commit();
    }
}

I had this problem and I couldn't find the solution here, so I want to share my solution in case someone else has this problem again.

I had this code:

public void finishAction() {
  onDestroy();
  finish();
}

and solved the problem by deleting the line "onDestroy();"

public void finishAction() {
  finish();
}

The reason I wrote the initial code: I know that when you execute "finish()" the activity calls "onDestroy()", but I'm using threads and I wanted to ensure that all the threads are destroyed before starting the next activity, and it looks like "finish()" is not always immediate. I need to process/reduce a lot of “Bitmap” and display big “bitmaps” and I’m working on improving the use of the memory in my app

Now I will kill the threads using a different method and I’ll execute this method from "onDestroy();" and when I think I need to kill all the threads.

public void finishAction() {
  onDestroyThreads();
  finish();
}

I had this issue and realized it was because I was calling setContentView(int id) twice in my Activity's onCreate


This one drove me crazy for Xamarin.

I ran into this with a ViewPager implementation for TabLayout WITHIN a Fragment, that is itself implemented in the DrawerLayout:

 - DrawerLayout
   - DrawerFragment
     - TabLayout
     - TabViewPager
       - TabViewPagerFragments

So you have to implement the following code in your DrawerFragment. Be aware to choose the correct FragmentManager-Path. Because you might have two different FragmentManager References:

  1. Android.Support.V4.App.FragmentManager
  2. Android.App.FragmentManager

--> Choose the one you use. If you want to make use of the ChildFragmentManager, you had to use the class declaration Android.App.FragmentManager for your ViewPager!

Android.Support.V4.App.FragmentManager

Implement the following Method in your "Main" Fragment - in this example: DrawerFragment

public override void OnDetach() {
    base.OnDetach();
    try {
        Fragment x = this;
        var classRefProp = typeof(Fragment).GetProperty("class_ref", BindingFlags.NonPublic | BindingFlags.Static);
        IntPtr classRef = (IntPtr)classRefProp.GetValue(x);
        var field = JNIEnv.GetFieldID(classRef, "mChildFragmentManager", "Landroid/support/v4/app/FragmentManagerImpl;");
        JNIEnv.SetField(base.Handle, field, IntPtr.Zero);
    }
    catch (Exception e) {
        Log.Debug("Error", e+"");
    }
}

Android.App.FragmentManager

public class TabViewPager: Android.Support.V13.App.FragmentPagerAdapter {}

That means you had to init the ViewPager with Android.App.FragmentManager.

Implement the following Method in your "Main" Fragment - in this example: DrawerFragment

public override void OnDetach() {
    base.OnDetach();
    try {
        Fragment x = this;
        var classRefProp = typeof(Fragment).GetProperty("class_ref", BindingFlags.NonPublic | BindingFlags.Static);
        IntPtr classRef = (IntPtr)classRefProp.GetValue(x);
        var field = JNIEnv.GetFieldID(classRef, "mChildFragmentManager", "Landroid/app/FragmentManagerImpl;");
        JNIEnv.SetField(base.Handle, field, IntPtr.Zero);
    }
    catch (Exception e) {
        Log.Debug("Error", e+"");
    }
}

참고URL : https://stackoverflow.com/questions/15207305/getting-the-error-java-lang-illegalstateexception-activity-has-been-destroyed

반응형