在使用带有ViewPager的选项卡时获取错误"Java.lang.IllegalStateException Activity已被销毁"

use*_*599 109 android android-fragments android-viewpager actionbarsherlock android-nested-fragment

我有一个应用程序,包括在选项卡模式下使用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) 
        {

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

没有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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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;  
        }  
   }
}
Run Code Online (Sandbox Code Playgroud)

从我在不同的地方阅读(如果我错了请纠正我),这是因为第二遍的片段管理器试图重新使用不再存在的活动中的片段,从而产生错误.但我不知道为什么会发生这种情况,因为我没有使用片段活动.根据logcat,错误在Tab2类中,onViewCreated方法在行上显示mViewPager.setAdapter(mMyFragmentPagerAdapter).非常感谢任何帮助...谢谢.

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)
Run Code Online (Sandbox Code Playgroud)

Mar*_*hre 284

这似乎是新添加的嵌套片段支持中的一个错误.基本上,当孩子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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 那么1年后,这个bug仍然没有修复?即使是最新的API和SDK更新,我也遇到了同样的错误...... (29认同)
  • 如果你看一下Fragment的实现,你会发现当它转移到分离状态时,它会重置它的内部状态.但是,它不会重置mChildFragmentManager(这是当前版本的支持库中的错误).这导致它在重新附加Fragment时不重新附加子片段管理器,从而导致您看到的异常. (20认同)
  • 你一定是在跟我开玩笑.很高兴你发现了这个,但很好的悲伤. (13认同)
  • Android开源问题跟踪器中正在跟踪此错误:https://code.google.com/p/android/issues/detail?id = 42601 (8认同)
  • 它似乎在支持库版本24.0.0中得到修复.'android.support.v4.app.Fragment'的方法'performDetach()','mChildFragmentManager = null;'. (6认同)
  • 一小撮盐,但这是使用support-v4版本或android.app版本失败.所以这个bug不仅发生在支持库中 (3认同)
  • 令人惊讶的是Android的风格如何; 我发誓谷歌只是讨厌开发人员. (2认同)
  • 如果我们在ViewPager中使用FragmentStatePagerAdapter它会崩溃:java.lang.NullPointerException E/AndroidRuntime(13225):at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:569)E/AndroidRuntime(13225):at android. support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:211) (2认同)
  • 你救了我的命.这个问题似乎在API> 20中得到修复,我在使用kitkat测试我的应用时是如此拉我的头发.. (2认同)
  • 在Lollipop似乎没有修复!! 哇超过2年半. (2认同)
  • 尝试[Android开源问题跟踪器](https://code.google.com/p/android/issues/detail?id=42601)中的所有解决方案,以及此解决方案,没有任何帮助.使用最新的Android SDK.在API 16和API 21设备上运行代码. (2认同)
  • 还是需要在androidx中解决? (2认同)

jek*_*att 13

我有完全相同的问题.我发现的唯一解决方法是每次更改选项卡时用新实例替换片段.

ft.replace(R.id.fragment_container, Fragment.instantiate(PlayerMainActivity.this, fragment.getClass().getName()));
Run Code Online (Sandbox Code Playgroud)

不是一个真正的解决方案,但我还没有找到重用前一个片段实例的方法......


use*_*133 7

super.onCreate()在我的方法结束时调用时遇到了同样的问题.原因:attachActivity()在FragmentActivity的onCreate()中调用.当覆盖onCreate()并且例如创建选项卡时,选项卡管理器将尝试切换到片段,而不将活动附加到FragmentManager.

简单的解决方案:将调用移动到super.onCreate()函数体的头部.

一般来说,似乎有很多原因可能会发生此问题.这只是另一个......

马蒂亚斯