I made a very simple Activity which shows a simple ListFragment like below:
My Activity:
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();
}
}
My 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));
}
...
}
When I start my app, I got error message:
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)
...
It complains that Activity has been destroyed, Why???
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>
As Fragment is embedded inside an Activity, it will be killed when Activity is killed. As contents of activity are first killed, fragment will be destroyed just before activity gets destroyed.
Since all fragments are destroyed if the activity is destroyed, a simple answer could be calling getActivity(). isDestroyed() returning true if the activity is destroyed, therefore the fragment is destroyed.
Fragment can't be initiated without Activity or FragmentActivity.
A fragment represents a modular portion of the user interface within an activity. A fragment has its own lifecycle, receives its own input events, and you can add or remove fragments while the containing activity is running. This document describes how to create a fragment and include it in an activity.
I also faced a similar problem.
I realized that this happened because the activity was being destroyed while the FragmentTransaction
was about to get .commit()
.
A solution to this was to check whether the Activity.isFinishing()
is true or not.
if (!isFinishing()) {
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.replace(SOME_RES_ID, myFragmentInstance);
ft.commit();
}
I figured out myself, It is because I missed the super.onCreate(savedInstanceState);
in my Activity onCreate() method . After added this, things are fine.
I faced the same issue and unable to fix it. Event I added isFinishing() check as well. but no luck.
then I added one more check isDestroyed() and its working fine now.
if (!isFinishing() && !isDestroyed()) {
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.replace(LAYOUT_ID, myFragmentInstance);
ft.commit();
}
To give an explanation:
The framework creates the Activity
and calls Activity.onCreate()
.
Activity.onCreate()
will somehow attach to the FragmentManager
to let it know about the hosting activity. Activity.onDestroy()
will unregister it again.
Now, you extend Activity
and override onCreate()
. You make calls to FragmentManager
without calling through toActivity.onCreate()
. The whole registration logic explained above is not executed. The FragmentManager
therefore does not know anything about the activity and assumes it has already been destroyed and generates the exception with the misleading error message.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With