Getting the error "Java.lang.IllegalStateException Activity has been destroyed" when using tabs with ViewPager

112,534

Solution 1

This seems to be a bug in the newly added support for nested fragments. Basically, the child FragmentManager ends up with a broken internal state when it is detached from the activity. A short-term workaround that fixed it for me is to add the following to onDetach() of every Fragment which you call getChildFragmentManager() on:

@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);
    }
}

Solution 2

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...

Solution 3

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

Solution 4

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.

Solution 5

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

Share:
112,534

Related videos on Youtube

Yulric Sequeira
Author by

Yulric Sequeira

Updated on December 28, 2020

Comments

  • Yulric Sequeira
    Yulric Sequeira over 3 years

    I have an application that consists of using ActionBarSherlock in tab mode.I have 5 tabs and the content of each tab is handled using fragments. For tab2 though, I have a fragment the xml file of which holds a ViewPager element which in turn has some fragment pages. When I initially start the application the application, I am able to switch between tabs no problem but when I press on tab2 for the second time I get the error mentioned above. The main activity is as follows:

    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) 
            {
    
            }
        }
    }
    

    The fragment class without the ViewPager is as follows:

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

    The fragment class with the ViewPager is as follows:

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

    From what I've read in different places (and please correct me if I'm wrong), this happens because the fragment manager on the second pass tries to reuse the fragments from the activity which doesn't exist anymore thus giving the error.But I'm not sure why this happens over here since I'm not using fragment activity. According to logcat the error is in the Tab2 class, onViewCreated method on the line that says mViewPager.setAdapter(mMyFragmentPagerAdapter). Any help is greatly appreciated...Thanks.

    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)
    
    • Yulric Sequeira
      Yulric Sequeira about 11 years
      So I think I may have found the problem. When looking at the variable mMyFragmentPagerAdapter(class Tab2) through the eclipse debugger, I saw that it had a FragmentManager variable which when clicking on Tab2 for the first time had a field called mActivity which was pointing to MainActivity.But on switching from tab2 to some other tab and looking at mActivity again it had a value of null, which perhaps explains why its giving the error Activity has been destroyed.
  • Yulric Sequeira
    Yulric Sequeira about 11 years
    Wow thanks a lot...that fixed the problem.Is it possible to give a explanation why it works?I was breaking my head trying to fix the error using the FragmentManager.
  • Yulric Sequeira
    Yulric Sequeira about 11 years
    Thanks a lot.This also seems to work. Is there a reaosn why you are setting the childFragmentManager to null in onDetach()?
  • Marcus Forsell Stahre
    Marcus Forsell Stahre about 11 years
    If you look at the implementation of Fragment, you'll see that when moving to the detached state, it'll reset its internal state. However, it doesn't reset mChildFragmentManager (this is a bug in the current version of the support library). This causes it to not reattach the child fragment manager when the Fragment is reattached, causing the exception you saw.
  • handrenliang
    handrenliang almost 11 years
    if we use FragmentStatePagerAdapter in ViewPager, it will crash when adapter tries to restore its data.
  • secureboot
    secureboot almost 11 years
    You have got to be kidding me. Glad you found posted this, but good grief.
  • StackOverflowed
    StackOverflowed over 10 years
    It's amazing how flakey Android is; I swear it feels like Google just hates developers.
  • kevinthompson
    kevinthompson over 10 years
    This bug is being tracked in the Android Open Source issue tracker: code.google.com/p/android/issues/detail?id=42601
  • apinho
    apinho about 10 years
    if we use FragmentStatePagerAdapter in ViewPager it crashes: java.lang.NullPointerException E/AndroidRuntime(13225): at android.support.v4.app.FragmentManagerImpl.getFragment(Fragm‌​entManager.java:569) E/AndroidRuntime(13225): at android.support.v4.app.FragmentStatePagerAdapter.restoreStat‌​e(FragmentStatePager‌​Adapter.java:211)
  • Muhammed Refaat
    Muhammed Refaat about 10 years
    what's mChildFragmentManager supposed to be?
  • ocross
    ocross almost 10 years
    @MuhammedRefaat that is the actual name in code of the child fragment manager field in the fragment class.
  • Muhammed Refaat
    Muhammed Refaat almost 10 years
    @ocross So, it's the actual name in the fragment class code not my own code? and so it has to be left as it is without any change?
  • gbero
    gbero almost 10 years
    A pinch of salt, but this is failing using the support-v4 version or the android.app version. So the bug not only occurs in the support library
  • nmxprime
    nmxprime over 9 years
    Have you analyzed your memory footprint? Because this workaround may increase it, at-least i suspect
  • nmxprime
    nmxprime over 9 years
    this doesn't solve my prob. But Thanks it helped me to correct my mistakes on using BroadcastReceivers
  • Rumit Patel
    Rumit Patel over 9 years
    Not any solution worked for me, i ended up with put it into try-catch... :-( i am using fragment into fragment which is into fragment.!!! another solution worked for me is i was using AsyncTask on start of nested fragment... i stop that asyncTask by calling mAsyncTask.cancel(true);
  • Hoa Vu
    Hoa Vu over 9 years
    @MarcusForsellStahre Could you take a look at this question about ViewPager? Thank you stackoverflow.com/questions/27937250/…
  • IgorGanapolsky
    IgorGanapolsky about 9 years
    What if your Activity context is null. Then 'this' wouldn't be valid.
  • Malachiasz
    Malachiasz about 9 years
    when Activities context can be null? I think never.
  • Kevin Prettre
    Kevin Prettre almost 9 years
    You saved my life. That issue seems fixed in API > 20, I was so pulling my hair when testing my app with kitkat..
  • Driss Bounouar
    Driss Bounouar over 8 years
    Doesn't seem to be fixed in Lollipop!! wow more than 2 years and a half.
  • azizbekian
    azizbekian over 8 years
    Tried all solutions in Android Open Source issue tracker, as well as this solution, nothing helps. Using the latest Android SDK. Running the code both on API 16 and API 21 device.
  • Iman Akbari
    Iman Akbari about 8 years
    thanks a lot. For anyone else having the same problem, if the error persists after applying this, you might wanna check if you're removing the fragment with "remove()" instead "detach()" .
  • X09
    X09 almost 8 years
    I was doing this: ` TagCatFragment tagCatFragment = TagCatFragment.newInstance(name, authorId, "Author"); tagCatFragment.show(getChildFragmentManager(), "TagCAatFragment");` and appying this solution. Didn't work.
  • Emerson Dallagnol
    Emerson Dallagnol almost 8 years
    It seems fixed in support library version 24.0.0. The method 'performDetach()', of 'android.support.v4.app.Fragment', do 'mChildFragmentManager = null;'.
  • Admin
    Admin over 7 years
    dont know why it works..dont know how it works but it works lol
  • 林果皞
    林果皞 over 5 years
    Seems already fixed in this commit, see android.googlesource.com/platform/frameworks/base/+/…
  • virengujariya
    virengujariya over 5 years
    Is this still necessary or fixed in androidx?
  • JonasPTFL
    JonasPTFL about 5 years
    Thank you very much, you saved my day! I had the same problem and could still not solve it after one week ;( . So im very happy you wrote this answer!!!
  • Syed Arsalan Kazmi
    Syed Arsalan Kazmi over 4 years
    You sir are a life savior!
  • Peter
    Peter about 4 years
    Going to emphasis word BUG from original answer. Anyone still using this, even if it still works, is doing something very wrong. This solution makes framework to crash stackoverflow.com/questions/56618453/…
  • SherylHohman
    SherylHohman over 3 years
    This reads to me more like a Comment, than an Answer. Regardless, however, please note that grammar, punctuation, capitalization, spelling, etc is important. Please edit to fix the issues. You can find more info in the SO help center at StackOverflow.com/help.