在ViewPager中使用选项卡时,出现错误“Java.lang.IllegalStateException活动已被破坏”

我有一个应用程序,包括使用ActionBarSherlock在标签mode.I有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; } } } 

从我在不同地方读到的(如果我错了,请纠正我),这是因为第二遍片段pipe理器试图重用不存在的活动中的片段,从而导致错误。但是我不确定为什么会发生在这里,因为我没有使用片段活动。 根据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) 

这似乎是新添加的嵌套片段支持中的一个错误。 基本上,子FragmentManager在从活动中分离出来时会以内部状态断开结束。 解决这个问题的一个短期解决方法是将以下内容添加到您调用getChildFragmentManager()的每个Fragment onDetach() 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); } } 

我有完全相同的问题。 我find的唯一的解决方法是每次更改选项卡时将新的实例replace为片段。

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

不是一个真正的解决scheme,但我还没有find一种方法来重用以前的片段实例…

在我的方法结束时调用super.onCreate()时遇到了同样的问题。 原因: attachActivity()在FragmentActivity的onCreate()中被调用。 当覆盖onCreate()和例如创build选项卡时,选项卡pipe理器将尝试切换到一个片段,而没有附加到FragmentManager的活动。

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

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

马蒂亚斯

想补充说我的问题是在我尝试在onCreate中做一个FragmentTransaction之前,我叫super.onCreate() 。 我只是把super.onCreate()移到了函数的顶部,工作正常。

我有这个错误,因为我使用LocalBroadcastManager,我做到了:

 unregisterReceiver(intentReloadFragmentReceiver); 

代替:

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

我遇到了同样的问题,后来发现,我错过了调用super.onCreate( savedInstanceState ); 在FragmentActivity的onCreate()

在片段完全初始化之前(即附加到Activity或至less调用了onCreateView() )试图访问子FragmentManager时,我得到了相同的错误。 否则, FragmentManager会被一个null Activity初始化,导致上述exception。

我在onPause强制包含子片段的片段为NULL,它修复了我的问题

 fragment = null; 

我知道这是一个旧post,但是build议的答案在我的结尾并不奏效。 我想离开这里,以防万一有人会发现它有用。

我做的是:

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

然后在:

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

我有这个问题,我找不到解决scheme,所以我想分享我的解决scheme,以防别人有这个问题了。

我有这样的代码:

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

并通过删除行“onDestroy();”来解决问题

 public void finishAction() { finish(); } 

我写的初始代码的原因是:我知道当你执行“finish()”时,activity会调用“onDestroy()”,但是我正在使用线程,并且我想确保所有线程在开始下一个活动之前被销毁,看起来“finish()”并不总是立即的。 我需要处理/减less很多“位图”,并显示大的“位图”,我正在努力改善我的应用程序中的内存使用

现在我将杀死线程使用不同的方法,我会执行这个方法从“onDestroy();” 当我想我需要杀死所有的线程。

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

我有这个问题,并意识到这是因为我在我的ActivityonCreate两次调用setContentView(int id)

这一个让我为Xamarin疯狂。

我用一个ViewPager实现了TabLayout WITHIN一个片段,这本身就是在DrawerLayout中实现的:

  - DrawerLayout - DrawerFragment - TabLayout - TabViewPager - TabViewPagerFragments 

所以你必须在你的DrawerFragment中实现下面的代码。 请注意select正确的FragmentManager-Path。 因为你可能有两个不同的FragmentManager引用:

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

– >select你使用的一个。 如果你想使用ChildFragmentManager,你必须为你的ViewPager使用类声明Android.App.FragmentManager

Android.Support.V4.App.FragmentManager

在你的“Main”片段中实现下面的方法 – 在这个例子中: 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 {} 

这意味着你必须用Android.App.FragmentManager来初始化ViewPager。

在你的“Main”片段中实现下面的方法 – 在这个例子中: 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+""); } }