我做了一个非常简单的活动,它显示了一个简单的 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>
答案 0 :(得分:67)
我也遇到过类似的问题
我意识到发生这种情况是因为在FragmentTransaction
即将获得.commit()
时活动正在被破坏。
解决方法是检查Activity.isFinishing()
是否为真。
if (!isFinishing()) {
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.replace(SOME_RES_ID, myFragmentInstance);
ft.commit();
}
答案 1 :(得分:32)
我想通了自己,这是因为我错过了我的Activity onCreate()方法中的super.onCreate(savedInstanceState);
。添加之后,一切都很好。
答案 2 :(得分:12)
我遇到了同样的问题但无法解决问题。 事件我添加了isFinishing()检查。但没有运气。
然后我又添加了一个检查 isDestroyed ()并且现在正常工作。
if (!isFinishing() && !isDestroyed()) {
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.replace(LAYOUT_ID, myFragmentInstance);
ft.commit();
}
答案 3 :(得分:4)
作出解释:
框架会创建Activity
并调用Activity.onCreate()
。
Activity.onCreate()
将以某种方式附加到FragmentManager
,让它知道托管活动。 Activity.onDestroy()
会再次取消注册。
现在,您展开Activity
并覆盖onCreate()
。您拨打FragmentManager
电话时无需致电Activity.onCreate()
。不执行上面解释的整个注册逻辑。 FragmentManager
因此对活动一无所知,并假设它已被销毁,并产生具有误导性错误消息的异常。
答案 4 :(得分:2)
为了确保我看到这一点,MyActivity是您尝试启动的活动,然后添加FirstFragment实例,对吗?
我立即看到了你需要看的两件事
1)在你的活动中,你永远不会调用setContentView()或super.onCreate()。第一次调用对你来说可能是个大问题,因为这意味着你的布局永远不会膨胀,因此,R变量不存在
2)您的MyActivity需要拥有自己的xml布局文件,而该文件没有。
答案 5 :(得分:1)
我所做的就是在提交后立即致电
fragmentManager.executePendingTransactions();
并且永远不会在onpause()
调用
阅读此Artical Fragment Transactions & Activity State Loss
答案 6 :(得分:1)
还不错,因为得到错误“活动已被破坏”
ava.lang.IllegalStateException: Activity has been destroyed fragmentTransaction.commitAllowingStateLoss();
所以我的解决方案是添加支票if (!isFinishing()&&!isDestroyed())
if (!isFinishing()&&!isDestroyed()) {
fragmentTransaction.commitAllowingStateLoss();
}
}
答案 7 :(得分:0)
super.onCreate(savedInstanceState)将调用FragmentActivity中的onCreate方法,该方法将调用mFragments.attachHost(null /*parent*/);
当您调用FragmentTransaction.commit()时,此句子将在FragmentController中为mHost
赋值;
在方法enqueueAction()
中,它有这句话
if (mDestroyed || mHost == null) {
throw new IllegalStateException("Activity has been destroyed");
}
因此,如果在提交fragmentTransaction之前没有调用super.onCreate(savedInstanceState),则会出现此异常,因为mHost为null
答案 8 :(得分:0)
如果有人遇到类似问题:
我正面临同样的问题,但在我的案例中,我从主要活动调用Fragment1然后如果用户点击Fragment1 Layout我想启动另一个Fragment2布局。
我能够从Main活动启动Fragment1但是Fragment1启动Fragment2失败,因为&#34;活动已被销毁&#34; 。
我通过在MainActivity类中将FragmentManager对象保持为静态来解决上述问题。 private static FragmentManager mfragmentManager = null;
使用相同的上述对象调用这两个片段,解决了我的问题。
以下是来自Main Activity的片段切换代码。
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();
}