仅在第二次导航到Fragment时导致java.IllegalStateException错误,无活动

use*_*524 35 android android-fragments android-viewpager actionbarsherlock android-support-library

我得到一个非常令人费解的错误,我不知道如何开始工作.

我有一个简单的应用程序,只有一个活动,视图是用Fragments实现的.其中一个片段里面有一个ViewPager; 所以我决定我想要使用v4支持库的getChildFragmentManager类.我还必须使用ActionBarSherlock,这会导致问题,因为它没有附带v4库的v11.

我通过用v11库替换ABS中的v4支持库来解决这个问题,所有编译好的东西都可以工作,包括ViewPager.

这是奇怪的部分:

第一次打开ViewPager的片段时,它可以正常工作; 但导航到的第二次,应用程序崩溃,给出了无用的堆栈跟踪.从调试开始,我发现问题出在getChildFragmentManager返回的FragmentManager上; 它会抛出No Activity错误.

有没有人知道是什么原因引起的?

我将发布您认为相关的代码.

谢谢你,大卫

lop*_*san 46

我按照jeremyvillalobos回答中的链接(这非常有帮助)引导我解决这个问题.

public class CustomFragment extends Fragment {
    private static final Field sChildFragmentManagerField;

    static {
        Field f = null;
        try {
            f = Fragment.class.getDeclaredField("mChildFragmentManager");
            f.setAccessible(true);
        } catch (NoSuchFieldException e) {
            Log.e(LOGTAG, "Error getting mChildFragmentManager field", e);
        }
        sChildFragmentManagerField = f;
    }

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

        if (sChildFragmentManagerField != null) {
            try {
                sChildFragmentManagerField.set(this, null);
            } catch (Exception e) {
                Log.e(LOGTAG, "Error setting mChildFragmentManager field", e);
            }
        }
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

它对我很有用,无需重新实现片段.


jer*_*bos 23

这似乎是一个报道的错误

https://code.google.com/p/android/issues/detail?id=42601

变量

FragmentManagerImpl mChildFragmentManager;

Fragment.java在分离时未设置为null.因此,下次加载片段时,变量仍然指向最后一个父级.

正如该线程所讨论的,解决方法是重新实现Fragment.

就我而言,我在ActionBar选项卡中切换片段.陷入困境的Fragment嵌套了Fragments,并在返回文件加载器Fragment时崩溃了应用程序.所以这是解决方法的代码:

class MainTabsListener implements ActionBar.TabListener {
    public Fragment fragment;
    public int TabPosition;

    public MainTabsListener(Fragment fragment, int tab_position) {
        this.fragment = fragment;
        TabPosition = tab_position;
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        CurrentFragment = fragment;
        CurrentTabSelectedPos = TabPosition;

        /**
         * This is a work-around for Issue 42601
         * https://code.google.com/p/android/issues/detail?id=42601
         * 
         * The method getChildFragmentManager() does not clear up
         * when the Fragment is detached.
         */
        if( fragment instanceof FileLoaderFragment ){
            fragment = reinstatiateFileLoaderFragment();
        }

        ft.replace(R.id.fragment_container, fragment);

    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        ft.remove(fragment);
    }

}
Run Code Online (Sandbox Code Playgroud)