J'ai fait un très simple Activité qui montre un simple ListFragment comme ci-dessous:
Mon activité:
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();
}
}
Mon 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));
}
...
}
Lorsque je lance mon application, je reçois un message d'erreur :
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)
...
Il se plaint que L'activité a été détruite , Pourquoi ???
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>
J'ai également fait face à un problème similaire.
J'ai réalisé que c'était parce que l'activité était en cours de destruction alors que la FragmentTransaction
était sur le point d'obtenir .commit()
.
Une solution à ce problème consistait à vérifier si Activity.isFinishing()
est vrai ou non.
if (!isFinishing()) {
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.replace(SOME_RES_ID, myFragmentInstance);
ft.commit();
}
Je me suis dit, c'est parce que j'ai raté la fonction super.onCreate(savedInstanceState);
dans ma méthode Activity onCreate (). Après avoir ajouté ceci, tout va bien.
J'ai rencontré le même problème et je suis incapable de le résoudre . L'événement auquel j'ai ajouté isFinishing () check également. mais pas de chance.
puis j'ai ajouté un autre check isDestroyed () et ça fonctionne bien maintenant.
if (!isFinishing() && !isDestroyed()) {
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.replace(LAYOUT_ID, myFragmentInstance);
ft.commit();
}
Pour donner une explication:
Le cadre crée la Activity
et appelle Activity.onCreate()
.
Activity.onCreate()
s'attachera d'une manière ou d'une autre à la FragmentManager
pour l'informer de l'activité d'hébergement. Activity.onDestroy()
le désenregistrera à nouveau.
Maintenant, vous étendez Activity
et remplacez onCreate()
. Vous téléphonez à FragmentManager
sans appeler toActivity.onCreate()
. Toute la logique d'enregistrement expliquée ci-dessus n'est pas exécutée. La FragmentManager
ne connaît donc rien de l'activité et suppose qu'elle a déjà été détruite et génère l'exception avec le message d'erreur trompeur.
Pour m'assurer que je vois bien, MyActivity est l'activité que vous essayez de lancer, puis ajoutez une instance de FirstFragment dans, n'est-ce pas?
Immédiatement, je vois deux choses que vous devez regarder
1) Dans votre activité, vous n’appelez jamais setContentView () ou super.onCreate (). Le premier appel pourrait être un gros problème pour vous car cela signifie que votre mise en page n'a jamais été gonflée et que, par conséquent, la variable R n'existe pas.
2) Votre MyActivity doit avoir son propre fichier de présentation XML, ce qui n’est pas le cas.
ce que j'ai fait, c'est tout de suite après que j'appelle
fragmentManager.executePendingTransactions();
et n'essayez jamais de vous engager après l'appel de onpause()
Lire cet article Fragment Transactions & Loss State Activity
Toujours aussi mauvais, parce que j'ai l'erreur "L'activité a été détruite"
ava.lang.IllegalStateException: Activity has been destroyed fragmentTransaction.commitAllowingStateLoss();
Donc, ma solution est d’ajouter check if (!isFinishing()&&!isDestroyed())
if (!isFinishing()&&!isDestroyed()) {
fragmentTransaction.commitAllowingStateLoss();
}
}
Si quelqu'un rencontre le même type de problème:
Je faisais face au même moment de problème, mais dans mon cas de Main Activity, j’appelais Fragment1 puis, si l’utilisateur clique sur Fragment1 Layout, je souhaite lancer un autre Fragment2 Layout.
J'ai pu lancer Fragment1 à partir de l'activité principale, mais Fragment1 à Fragment2 ne fonctionnait pas, sauf que "L'activité a été détruite" .
J'ai résolu le problème ci-dessus en maintenant l'objet FragmentManager statique dans la classe MainActivity . private FragmentManager statique mfragmentManager = null;
appeler les deux fragments en utilisant le même objet, résolut mon problème.
Vous trouverez ci-dessous le code de commutation de fragment de l'activité principale.
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();
}
super.onCreate (savedInstanceState) appellera la méthode onCreate dans FragmentActivity, qui appellera mFragments.attachHost(null /*parent*/);
Cette phrase assignera une valeur à mHost
dans FragmentController, lorsque vous appelez FragmentTransaction.commit (),
Dans la méthode enqueueAction()
, il a cette phrase
if (mDestroyed || mHost == null) {
throw new IllegalStateException("Activity has been destroyed");
}
Donc, si vous n'avez pas appelé super.onCreate (savedInstanceState) avant de valider une transaction fragmentTransaction, vous obtiendrez cette exception car mHost est null