18

我做了一个非常简单的活动其中显示了一个简单ListFragment象下面这样:非常简单的代码,但遇到错误“活动已被破坏”的时候使用片段

我的活动:

public class MyActivity extends FragmentActivity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
      FragmentManager fragMgr = getSupportFragmentManager(); 

      FirstFragment list = new FirstFragment(); 
      fragMgr.beginTransaction().add(android.R.id.content, list).commit(); 
    } 

} 

我ListFragment:

public class FirstFragment extends ListFragment{ 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     inflater.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     View view = inflater.inflate(R.layout.main, null); 
     return view; 
    } 


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

     String listContent[] = {"Larry", "Moe", "Curly"}; 
     setListAdapter(new ArrayAdapter<String>(getActivity(), R.layout.list_item, listContent)); 
    } 
    ... 
} 

当我开始我的应用程序,我得到了错误消息

java.lang.IllegalStateException: Activity has been destroyed 
E/AndroidRuntime( 947): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496) 
E/AndroidRuntime( 947): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512) 
E/AndroidRuntime( 947): at android.app.ActivityThread.access$2200(ActivityThread.java:119) 
E/AndroidRuntime( 947): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863) 
E/AndroidRuntime( 947): at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime( 947): at android.os.Looper.loop(Looper.java:123) 
E/AndroidRuntime( 947): at android.app.ActivityThread.main(ActivityThread.java:4363) 
E/AndroidRuntime( 947): at java.lang.reflect.Method.invokeNative(Native Method) 
... 

它抱怨活动已被破坏为什么???

P.S. main.xml中:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:paddingLeft="8dp" 
    android:paddingRight="8dp"> 

    <Button 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="next" /> 

    <ListView 
    android:id="@android:id/list" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#00FF00" 
    android:layout_weight="1" 
    android:drawSelectorOnTop="false" /> 

    <TextView 
    android:id="@android:id/empty" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#FF0000" 
    android:text="No data" /> 
</LinearLayout> 

回答

28

我想通了我自己,那是因为我错过了在我的活动onCreate()方法的super.onCreate(savedInstanceState);。添加后,事情很好。

+1

注意,你可能会接受你的答案为最佳答案 – 2012-02-03 17:03:39

+6

如果有人能解释深层原因,我会接受更好的不是我的:) – 2012-02-03 17:10:09

+1

在我的情况下,我打电话给super.onCreate(savedInstanceState);在添加片段之后。 – Ankit 2014-02-24 15:55:46

2

为了确保我看到这个权利,MyActivity是您尝试启动的活动,然后将FirstFragment的实例添加到,对吧?

我立刻知道你需要看看

1两件事情)在你的活动,你永远不会调用的setContentView()或者super.onCreate()。第一个电话对你来说可能是一个巨大的问题,因为这意味着你的布局从来没有膨胀,因此,R变量不存在

2)你的MyActivity需要有它自己的xml布局文件,没有。

+0

嗨,我不认为一个活动必须有一个布局文件,例如,我的代码工作后,我添加了super.onCreate(...),我的活动只是一个片段,并且该片段将膨胀布局为显示,而不是活动。 – 2012-02-03 17:06:52

+0

这是可能的,因为我没有真正使用过支持包。我的大部分开发都是使用多窗格布局的Honeycomb。我只是看着API文档,我认为你是对的。感谢您指出了这一点! – 2012-02-03 17:10:15

+0

没问题,我也是新来的支持包,我从今天开始学习片段:) – 2012-02-03 17:11:27

4

给予解释:

框架创建Activity并调用Activity.onCreate()

Activity.onCreate()将以某种方式附加到FragmentManager以让其知道主办活动。 Activity.onDestroy()将再次取消注册。

现在,您扩展Activity并覆盖onCreate()。您拨打电话FragmentManager时不需拨打Activity.onCreate()。上面解释的整个注册逻辑不会被执行。因此,FragmentManager不知道任何有关该活动的信息,并假定它已被销毁并生成具有误导性错误消息的异常。

68

我也遇到类似的问题。
我意识到这是因为活动正在被破坏,而FragmentTransaction即将得到.commit()

解决方法是检查Activity.isFinishing()是否为真。

if (!isFinishing()) { 
    FragmentTransaction ft = getSupportFragmentManager() 
    .beginTransaction(); 
    ft.replace(SOME_RES_ID, myFragmentInstance); 
    ft.commit(); 
} 
+0

感谢它为我工作!通过[Github上的讨论]来到这里(https://github.com/JakeWharton/ActionBarSherlock/issues/1031)。感谢分享。 – 2016-02-11 10:33:35

10

我面临着同样的问题并无法修复它。 事件我添加了isFinishing()检查。但没有运气。

然后我又添加了一个检查isDestroyed(),现在工作正常。

if (!isFinishing() && !isDestroyed()) { 
    FragmentTransaction ft = getSupportFragmentManager() 
    .beginTransaction(); 
    ft.replace(LAYOUT_ID, myFragmentInstance); 
    ft.commit(); 
} 
+1

请注意,onDestroyed()是在API级别17中添加的。 – Gira 2017-02-21 06:19:50

0

super.onCreate(savedInstanceState)将调用的onCreate在FragmentActivity方法,它会调用mFragments.attachHost(null /*parent*/);

这句话将在FragmentController的值赋给mHost,当你调用FragmentTransaction.commit(),

在该方法中enqueueAction(),它有这个句子

if (mDestroyed || mHost == null) { 
     throw new IllegalStateException("Activity has been destroyed"); 
} 

所以,如果你有没有打电话super.onCreate(savedInstanceState)你提交fragmentTransaction之前,你会得到这个异常,因为mHost为空

0

如果遇到类似的问题类型中的任何一个来:

我面临的同一时间问题,但在我从主要活动的情况下,我打电话给Fragment1,然后如果用户点击Fragment1 Layout,我想启动另一个Fragment2 Layout。

我能够从主要活动启动Fragment1,但Fragment1到Fragment2它失败,例外情况为“活动已被销毁”

我通过在MainActivity类中将FragmentManager对象保持为静态解决了上述问题。 private static FragmentManager mfragmentManager = null;

使用上述相同的对象调用这两个片段,解决了我的问题。

以下是来自主要活动的我的片段切换代码。

public void switchToFragment(String fragmentName){ 
     Fragment fragment = null; 
     switch (fragmentName) { 
      case "Fragment1":{ 
       fragment = new Fragment1(); 
       break; 
      } 
      case "Fragment2": { 
       fragment = new Fragment2(); 
       break; 
      } 
     } 

     FragmentTransaction transaction = mfragmentManager.beginTransaction(); 
     transaction.replace(R.id.fragment_container, fragment); 
     transaction.commit(); 
    } 
1

仍然很糟糕,因为出现错误“的活动已被破坏”

ava.lang.IllegalStateException: Activity has been destroyed fragmentTransaction.commitAllowingStateLoss(); 

所以我的解决办法是添加复if (!isFinishing()&&!isDestroyed())

if (!isFinishing()&&!isDestroyed()) { 
         fragmentTransaction.commitAllowingStateLoss(); 
        } 
       } 
相关问题