【问题标题】:IllegalStateException: Fragment <ThisFragment> is not currently in the FragmentManagerIllegalStateException: Fragment <ThisFragment> 当前不在 FragmentManager 中
【发布时间】:2014-03-01 08:35:47
【问题描述】:

我无法在我的应用中追踪崩溃的原因。我有一个显示ListView 的片段,我也有SlidingMenu 用于搜索字段。当我搜索时,ListView 项目会根据搜索结果重新填充。现在,当我尝试从新填充的结果中打开 ListView 项目时,我的应用程序崩溃了。

这里触发了异常:

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getSupportFragmentManager().putFragment(outState, "mContent", mContent); //Exception made here
}

这是因为支持库吗?我该如何解决这个问题?

编辑:

这是堆栈跟踪:

02-05 12:51:53.941: E/AndroidRuntime(11638): FATAL EXCEPTION: main
02-05 12:51:53.941: E/AndroidRuntime(11638): java.lang.IllegalStateException: Fragment MyFragment{436749b0} is not currently in the FragmentManager
02-05 12:51:53.941: E/AndroidRuntime(11638):    at android.support.v4.app.FragmentManagerImpl.putFragment(FragmentManager.java:546)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at com.sample.android.app.SearchListActivity.onSaveInstanceState(SearchListActivity.java:118)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at android.app.Activity.performSaveInstanceState(Activity.java:1137)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1215)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:2972)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3031)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at android.app.ActivityThread.access$900(ActivityThread.java:138)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at android.os.Handler.dispatchMessage(Handler.java:99)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at android.os.Looper.loop(Looper.java:213)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at android.app.ActivityThread.main(ActivityThread.java:4787)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at java.lang.reflect.Method.invokeNative(Native Method)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at java.lang.reflect.Method.invoke(Method.java:511)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
02-05 12:51:53.941: E/AndroidRuntime(11638):    at dalvik.system.NativeStart.main(Native Method)

编辑 2: 这是我的活动:

private Fragment mFragment;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

            ..........

    params = new Bundle();
    params.putInt("id", id);

    // set the Above View Fragment
    if (savedInstanceState != null)
        mFragment = getSupportFragmentManager().getFragment(
                savedInstanceState, "mFragment");
    else {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager
                .beginTransaction();
        SampleListFragment fragment = new SampleListFragment();
        fragment.setArguments(params);
        fragmentTransaction.add(R.id.list_fragment, fragment);
        fragmentTransaction.commit();
    }

    if (mFragment == null) {
        mFragment = new SampleListFragment();
        mFragment.setArguments(params);
    }
    getSupportFragmentManager().beginTransaction()
            .replace(R.id.list_fragment, mFragment).commit();

    // set the Behind View Fragment
    Fragment searchFragment = new SampleSearchFragment();
    searchFragment.setArguments(params);

    getSupportFragmentManager().beginTransaction()
            .replace(R.id.activity_search, searchFragment)
            .commit();
}


@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getSupportFragmentManager().putFragment(outState, "mFragment",
            mFragment);
}

在我的SampleListFragment,我有这个方法:

public static boolean isNetworkAvailable(Activity activity) {
    ConnectivityManager connectivity = (ConnectivityManager) activity
            .getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivity == null) {
        return false;
    } else {
        NetworkInfo[] info = connectivity.getAllNetworkInfo();
        if (info != null) {
            for (int i = 0; i < info.length; i++) {
                if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                    return true;
                }
            }
        }
    }
    return false;
}

Asynctask内部:

..........
@Override
protected void onPostExecute(String result) {
    super.onPostExecute(null);

    if (null != pDialog && pDialog.isShowing()) {
        pDialog.dismiss();
    }

    if (isNetworkAvailable(getActivity())) { //Triggered NPE

来自here,在调用之前我如何知道getActivity() 现在是否附加到父活动?

【问题讨论】:

  • 检查this
  • 你添加了那个片段吗?
  • @SweetWisherツ 我把它换成了getSupportFragmentManager().beginTransaction().add(R.id.list_fragment, mFragment, "mFragment").commit();,就像你的链接一样。现在的问题是,在我的MyFragment 中,我在代码中的某处使用了getActivity(),但现在它调用了NullPointerException
  • 现在显示更新的 logcat
  • 显示触发 NullPointer 异常的行

标签: android android-fragments nullpointerexception android-support-library illegalstateexception


【解决方案1】:

在将片段保存到onSaveInstanceState 之前,请确保检查片段是否已添加到片段管理器中

@Override 
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    if (mFragment.isAdded()){
        getSupportFragmentManager().putFragment(outState, "mFragment", mFragment); 
    }
} 

【讨论】:

  • 完美!我知道会有一些方法可以检查这一点。
【解决方案2】:

我也面临同样的问题。当我尝试将片段放入

中的 bundleState 时
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    getSupportFragmentManager().putFragment(outState, "mContent",   mContent); //Exception made here
}

我检查了FragmentManagerputFragment() 方法的实现。就像

 @Override
 public void putFragment(Bundle bundle, String key, Fragment fragment) {
    if (fragment.mIndex < 0) {
         throwException(new IllegalStateException("Fragment " + fragment
                    + " is not currently in the FragmentManager"));
    }
    bundle.putInt(key, fragment.mIndex);
  }

其中mIndex 是活动片段数组的片段索引。因此,如果mIndex &lt; 0 表示片段当前未处于活动状态。所以@FelipeConde 建议检查mFragment.isAdded() 可能是最好的解决方案。

【讨论】:

    【解决方案3】:

    在我的例子中,我有 2 个片段(PopularMoviesFragment 和 TopRatedMoviesFragment),PopularMoviesFragment 填充在 Activity 的 onCreate 中,另一个将通过单击 底部导航视图。

    所以当我打开应用程序并且没有点击 BottomNavigationView 如果我最小化(或导航到其他应用程序)时,我得到了这个异常

    java.lang.IllegalStateException: Fragment TopRatedMoviesFragement{79d8905} 当前不在 FragmentManager 中

    我在 onCreate() 中的代码是

    if (currentSelectedbottomNavigation.equals(FRAGMENT_1)) {
    
            fragmentManager.beginTransaction()
                    .replace(R.id.containerw, fragment_1, FRAGMENT_1)
                    .addToBackStack(null)
                    .commit();
        }else if (currentSelectedbottomNavigation.equals(FRAGMENT_2)){   
    
            fragmentManager.beginTransaction()
                    .replace(R.id.container, fragment_2, FRAGMENT_2)
                    .addToBackStack(null)
                    .commit();
        }
    

    因此我所做的只是添加了TopRatedMoviesFragment,然后将其替换为PopularMoviesFragment,如下代码所示。

    if (currentSelectedbottomNavigation.equals(FRAGMENT_1)) {
    
            fragmentManager.beginTransaction()
                    .add(R.id.container, fragment_2, FRAGMENT_2)
                    // Its been added to avoid Fragment is not currently in the FragmentManager
                    .replace(R.id.container, fragment_1, FRAGMENT_1)
                    .addToBackStack(null)
                    .commit();
        }else if (currentSelectedbottomNavigation.equals(FRAGMENT_2)){  
    
            fragmentManager.beginTransaction()
                    .replace(R.id.container, fragment_2, FRAGMENT_2)
                    .addToBackStack(null)
                    .commit();
        }
    

    希望这也有帮助。 :)

    【讨论】:

      【解决方案4】:

      最近,我遇到了同样的问题。 就我而言,当调用活动的 onBackPressed() 时,我忘记设置 mFragment 。也就是说,当用户在 A -> B -> C 中导航时,mFragment 会相应地更改为 A,然后是 B,最后是 C。但是,当按下返回时,当前 Fragment 会反向更改为 B,然后是 A,但 mFragment 是仍然是 C。因此,在 onSaveInstanceState 期间,Activity 会尝试保存不在 FragmentManager 中的 C。

      重点是,您可能正在更改(添加或删除)当前 [显示] 片段,而没有适当更改 mFragment。

      【讨论】:

        【解决方案5】:

        在我的例子中,Fragment 通过 FragmentPagerAdapter 添加到 ViewPager 以便有多个选项卡,每个选项卡有 1 个片段。

            List<Android.Support.V4.App.Fragment> lsFragments = new List<Android.Support.V4.App.Fragment>();
            lsFragments.Add(m_FragmentListDocument);
            lsFragments.Add(m_FragmentListNote);
            lsFragments.Add(m_FragmentListRenvoi);
        
            m_viewPager.Adapter = new TabsFragmentPagerAdapter(SupportFragmentManager, lsFragments, lsTitles);
        

        在我的 OnSaveInstanceState 中,我想保存所有选项卡,但是 1 个选项卡正在抛出异常 Java.Lang.IllegalStateException: Fragment is not currently in the FragmentManager

        protected override void OnSaveInstanceState(Bundle outState)
        {
            base.OnSaveInstanceState(outState);
        
            SupportFragmentManager.PutFragment(outState, "FragmentListDocument", m_FragmentListDocument);
            SupportFragmentManager.PutFragment(outState, "FragmentListNote", m_FragmentListNote);
            SupportFragmentManager.PutFragment(outState, "FragmentListRenvoi", m_FragmentListRenvoi);
        }
        

        这是由于 ViewPager : ViewPager 加载屏幕上显示的当前片段和(默认情况下)左侧和右侧的片段。

        所以在这种情况下,我修改了 ViewPager 以将 OffscreenPageLimit 设置得足够高,以便在启动时加载所有 Fragment。然后将片段添加到 SupportFragmentManager 并且 OnSaveInstanceState 中没有抛出异常。

        m_viewPager.OffscreenPageLimit = 4;
        

        希望对您有所帮助...

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-07-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-07-12
          • 2016-12-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多