java.lang.IllegalStateException: impossible d’effectuer cette action après onSaveInstanceState

J’utilise la bibliothèque de support pour mon application. Dans mon FragmentActivity, j’utilise un AsyncTask pour télécharger des données depuis Internet. Dans la méthode onPreExecute (), j’ajoute un fragment et dans la méthode onPostExecute () je le supprime à nouveau. Lorsque l’orientation est modifiée entre les deux, j’obtiens l’exception mentionnée ci-dessus. S’il vous plaît jeter un oeil aux détails:

private class onFriendAddedAsyncTask extends AsyncTask { DummyFragment dummyFragment; FragmentManager fm; FragmentTransaction ft; @Override protected void onPreExecute() { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute"); dummyFragment = DummyFragment.newInstance(); fm = getSupportFragmentManager(); ft = fm.beginTransaction(); ft.add(dummyFragment, "dummy_fragment"); ft.commit(); } @Override protected void onPostExecute(Ssortingng result) { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute"); ft = fm.beginTransaction(); ft.remove(dummyFragment); ft.commit(); } @Override protected Ssortingng doInBackground(Ssortingng... name) { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/doInBackground"); ... } 

Je suis la suite de LogCut:

 01-05 23:54:19.958: V/MyFragmentActivity(12783): onFriendAddedAsyncTask/onPreExecute 01-05 23:54:19.968: V/DummyFragment(12783): onAttach 01-05 23:54:19.968: V/DummyFragment(12783): onCreate 01-05 23:54:19.968: V/MyFragmentActivity(12783): onFriendAddedAsyncTask/doInBackground 01-05 23:54:19.973: V/DummyFragment(12783): onCreateView 01-05 23:54:19.973: V/DummyFragment(12783): onActivityCreated 01-05 23:54:19.973: V/DummyFragment(12783): onStart 01-05 23:54:19.973: V/DummyFragment(12783): onResume 01-05 23:54:21.933: V/MyFragmentActivity(12783): onSaveInstanceState 01-05 23:54:21.933: V/DummyFragment(12783): onSaveInstanceState 01-05 23:54:21.933: V/MyFragmentActivity(12783): onPause 01-05 23:54:21.933: V/DummyFragment(12783): onPause 01-05 23:54:21.938: V/MyFragmentActivity(12783): onStop 01-05 23:54:21.938: V/DummyFragment(12783): onStop 01-05 23:54:21.938: V/MyFragmentActivity(12783): onDestroy 01-05 23:54:21.938: V/DummyFragment(12783): onDestroyView 01-05 23:54:21.938: V/DummyFragment(12783): onDestroy 01-05 23:54:21.938: V/DummyFragment(12783): onDetach 01-05 23:54:21.978: V/MyFragmentActivity(12783): onCreate 01-05 23:54:21.978: V/DummyFragment(12783): onAttach 01-05 23:54:21.978: V/DummyFragment(12783): onCreate 01-05 23:54:22.263: V/MyFragmentActivity(12783): onStart 01-05 23:54:22.313: V/DummyFragment(12783): onCreateView 01-05 23:54:22.313: V/DummyFragment(12783): onActivityCreated 01-05 23:54:22.313: V/DummyFragment(12783): onStart 01-05 23:54:22.323: V/MyFragmentActivity(12783): onResume 01-05 23:54:22.323: V/MyFragmentActivity(12783): onPostResume 01-05 23:54:22.323: V/MyFragmentActivity(12783): onResumeFragments 01-05 23:54:22.323: V/DummyFragment(12783): onResume 01-05 23:54:27.123: V/MyFragmentActivity(12783): onFriendAddedAsyncTask/onPostExecute 01-05 23:54:27.123: D/AndroidRuntime(12783): Shutting down VM 01-05 23:54:27.123: W/dalvikvm(12783): threadid=1: thread exiting with uncaught exception (group=0x4001d7d0) 01-05 23:54:27.138: E/AndroidRuntime(12783): FATAL EXCEPTION: main 01-05 23:54:27.138: E/AndroidRuntime(12783): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1314) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1325) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:532) 01-05 23:54:27.138: E/AndroidRuntime(12783): at com.xyz.dummy.MyFragmentActivity$onFriendAddedAsyncTask.onPostExecute(MyFragmentActivity.java:447) 01-05 23:54:27.138: E/AndroidRuntime(12783): at com.xyz.dummy.MyFragmentActivity$onFriendAddedAsyncTask.onPostExecute(MyFragmentActivity.java:1) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.AsyncTask.finish(AsyncTask.java:417) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.AsyncTask.access$300(AsyncTask.java:127) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.Handler.dispatchMessage(Handler.java:99) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.os.Looper.loop(Looper.java:123) 01-05 23:54:27.138: E/AndroidRuntime(12783): at android.app.ActivityThread.main(ActivityThread.java:4627) 01-05 23:54:27.138: E/AndroidRuntime(12783): at java.lang.reflect.Method.invokeNative(Native Method) 01-05 23:54:27.138: E/AndroidRuntime(12783): at java.lang.reflect.Method.invoke(Method.java:521) 01-05 23:54:27.138: E/AndroidRuntime(12783): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 01-05 23:54:27.138: E/AndroidRuntime(12783): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 01-05 23:54:27.138: E/AndroidRuntime(12783): at dalvik.system.NativeStart.main(Native Method) 

Dans d’autres discussions sur des problèmes similaires, la raison semble être que la méthode onPostExecute est appelée avant d’appeler la méthode onResume (). Mais j’obtiens l’exception même si onResume () est appelé avant.

Est-ce que quelqu’un sait ce qui ne va pas?

L’activité ressemble à ceci:

 public class MyFragmentActivity extends FragmentActivity implements OnFriendSelectedListener, OnFriendAddedListener, OnFriendOptionSelectedListener, LoaderCallbacks { @Override public void onCreate(Bundle savedInstanceState) { Log.v("MyFragmentActivity", "onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.fragment_activity_layout); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); FriendListFragment friendListFragment = (FriendListFragment)fm.findFragmentById(R.id.friend_list_fragment_layout); if (friendListFragment == null) { friendListFragment = new FriendListFragment(); ft.add(R.id.friend_list_fragment_layout, friendListFragment); ft.commit(); fm.executePendingTransactions(); startService(new Intent(this, MyIntentService.class)); getSupportLoaderManager().initLoader(CHECK_EMPTY_DATABASE, null, this); } } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.fragment_activity_options_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { super.onOptionsItemSelected(item); switch (item.getItemId()) { case R.id.add_friend_menu_item: AddFriendDialogFragment addFriendDialogFragment = AddFriendDialogFragment.newInstance(); addFriendDialogFragment.show(getSupportFragmentManager(), "add_friend_dialog_fragment"); return true; default: return false; } } @Override public void onFriendAdded(Ssortingng name) { name = name.sortingm(); if (name.length() > 0) { new onFriendAddedAsyncTask().execute(name); } } 

Lorsque j’utilise commitAllowingStateLoss (), j’obtiens l’exception suivante:

 01-06 14:54:29.548: E/AndroidRuntime(18020): FATAL EXCEPTION: main 01-06 14:54:29.548: E/AndroidRuntime(18020): java.lang.IllegalStateException: Activity has been destroyed 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1329) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:536) 01-06 14:54:29.548: E/AndroidRuntime(18020): at com.xyz.dummy.FadiaFragmentActivity$onFriendAddedAsyncTask.onPostExecute(FadiaFragmentActivity.java:461) 01-06 14:54:29.548: E/AndroidRuntime(18020): at com.xyz.dummy.FadiaFragmentActivity$onFriendAddedAsyncTask.onPostExecute(FadiaFragmentActivity.java:1) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.AsyncTask.finish(AsyncTask.java:417) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.AsyncTask.access$300(AsyncTask.java:127) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.Handler.dispatchMessage(Handler.java:99) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.os.Looper.loop(Looper.java:123) 01-06 14:54:29.548: E/AndroidRuntime(18020): at android.app.ActivityThread.main(ActivityThread.java:4627) 01-06 14:54:29.548: E/AndroidRuntime(18020): at java.lang.reflect.Method.invokeNative(Native Method) 01-06 14:54:29.548: E/AndroidRuntime(18020): at java.lang.reflect.Method.invoke(Method.java:521) 01-06 14:54:29.548: E/AndroidRuntime(18020): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 01-06 14:54:29.548: E/AndroidRuntime(18020): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 01-06 14:54:29.548: E/AndroidRuntime(18020): at dalvik.system.NativeStart.main(Native Method) 

Je reçois le même IllegalStateExeption lorsque j’implémente AsynTask comme suit, car la méthode findFragmentById () renvoie un pointeur null.

 private class onFriendAddedAsyncTask extends AsyncTask { protected void onPreExecute() { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute"); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); DummyFragment dummyFragment = DummyFragment.newInstance(); ft.add(R.id.dummy_fragment_layout, dummyFragment); ft.commit(); } protected void onPostExecute(Ssortingng result) { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute"); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); DummyFragment dummyFragment = (DummyFragment) fm.findFragmentById(R.id.dummy_fragment_layout); ft.remove(dummyFragment); ft.commitAllowingStateLoss(); } 

À l’étape suivante, j’utilise un gestionnaire pour l’ajout et la suppression du factice factice. De plus, j’ai ajouté des sorties de débogage supplémentaires.

 private class onFriendAddedAsyncTask extends AsyncTask { @Override protected void onPreExecute() { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager()); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout)); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout)); new Handler().post(new Runnable() { public void run() { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager()); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout)); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPreExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout)); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); DummyFragment dummyFragment = DummyFragment.newInstance(); ft.add(R.id.dummy_fragment_layout, dummyFragment); ft.commit(); } }); @Override protected void onPostExecute(Ssortingng result) { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager()); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout)); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout)); new Handler().post(new Runnable() { public void run() { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager()); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.dummy_fragment_layout)); Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute " + getSupportFragmentManager().findFragmentById(R.id.friend_list_fragment_layout)); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); DummyFragment dummyFragment = (DummyFragment) fm.findFragmentById(R.id.dummy_fragment_layout); ft.remove(dummyFragment); ft.commitAllowingStateLoss(); } }); 

Je suis la suite de LogCut:

 01-07 19:00:17.273: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FragmentManager{45e384a8 in MyFragmentActivity{45e38358}} 01-07 19:00:17.273: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute null 01-07 19:00:17.273: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FriendListFragment{45e38ab0 #0 id=0x7f0a0002} 01-07 19:00:17.283: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FragmentManager{45e384a8 in MyFragmentActivity{45e38358}} 01-07 19:00:17.288: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/doInBackground 01-07 19:00:17.288: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute null 01-07 19:00:17.288: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPreExecute FriendListFragment{45e38ab0 #0 id=0x7f0a0002} 01-07 19:00:17.308: V/DummyFragment(4124): onAttach DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:17.308: V/DummyFragment(4124): onCreate DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:17.308: V/DummyFragment(4124): onCreateView DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:17.308: V/DummyFragment(4124): onActivityCreated DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:17.308: V/DummyFragment(4124): onStart DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:17.313: V/DummyFragment(4124): onResume DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.098: V/MyFragmentActivity(4124): onSaveInstanceState DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.098: V/DummyFragment(4124): onSaveInstanceState DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.098: V/MyFragmentActivity(4124): onPause DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.098: V/DummyFragment(4124): onPause DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.103: V/MyFragmentActivity(4124): onStop DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.103: V/DummyFragment(4124): onStop DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.103: V/MyFragmentActivity(4124): onDestroy DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.103: V/DummyFragment(4124): onDestroyView DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.108: V/DummyFragment(4124): onDestroy DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.113: V/DummyFragment(4124): onDetach DummyFragment{45dd7498 #2 id=0x7f0a0004} 01-07 19:00:18.138: V/MyFragmentActivity(4124): onCreate 01-07 19:00:18.138: V/FriendListFragment(4124): FriendListFragment 01-07 19:00:18.138: V/FriendListFragment(4124): onAttach FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.138: V/FriendListFragment(4124): onCreate FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.148: V/DummyFragment(4124): onAttach DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.153: V/DummyFragment(4124): onCreate DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.523: V/MyFragmentActivity(4124): onStart DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.543: V/FriendListFragment(4124): onActivityCreated FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.548: V/DummyFragment(4124): onCreateView DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.548: V/DummyFragment(4124): onActivityCreated DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.548: V/FriendListFragment(4124): onLoadFinished FragmentManager{45d8e478 in MyFragmentActivity{45e4a6d8}} 01-07 19:00:18.548: V/FriendListFragment(4124): onLoadFinished FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.553: V/DummyFragment(4124): onStart DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.553: V/FriendListFragment(4124): onLoadFinished FragmentManager{45d8e478 in MyFragmentActivity{45e4a6d8}} 01-07 19:00:18.553: V/FriendListFragment(4124): onLoadFinished FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.558: V/MyFragmentActivity(4124): onResume DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.558: V/MyFragmentActivity(4124): onPostResume DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.558: V/MyFragmentActivity(4124): onResumeFragments DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.558: V/FriendListFragment(4124): onResume FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.563: V/FriendListFragment(4124): onCreateLoader FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.563: V/DummyFragment(4124): onResume DummyFragment{45d7d1a0 #2 id=0x7f0a0004} 01-07 19:00:18.723: V/FriendListFragment(4124): onLoadFinished FragmentManager{45d8e478 in MyFragmentActivity{45e4a6d8}} 01-07 19:00:18.723: V/FriendListFragment(4124): onLoadFinished FriendListFragment{45e4a7f8 #0 id=0x7f0a0002} 01-07 19:00:18.893: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute FragmentManager{45e384a8 in null}} 01-07 19:00:18.893: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null 01-07 19:00:18.893: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null 01-07 19:00:18.923: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute FragmentManager{45e384a8 in null}} 01-07 19:00:18.923: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null 01-07 19:00:18.923: V/MyFragmentActivity(4124): onFriendAddedAsyncTask/onPostExecute null 01-07 19:00:18.928: D/AndroidRuntime(4124): Shutting down VM 01-07 19:00:18.928: W/dalvikvm(4124): threadid=1: thread exiting with uncaught exception (group=0x4001d7d0) 01-07 19:00:18.938: E/AndroidRuntime(4124): FATAL EXCEPTION: main 01-07 19:00:18.938: E/AndroidRuntime(4124): java.lang.IllegalStateException: Activity has been destroyed 01-07 19:00:18.938: E/AndroidRuntime(4124): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1329) 01-07 19:00:18.938: E/AndroidRuntime(4124): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548) 01-07 19:00:18.938: E/AndroidRuntime(4124): at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:536) 01-07 19:00:18.938: E/AndroidRuntime(4124): at com.xyz.dummy.MyFragmentActivity$onFriendAddedAsyncTask$2.run(MyFragmentActivity.java:476) 01-07 19:00:18.938: E/AndroidRuntime(4124): at android.os.Handler.handleCallback(Handler.java:587) 01-07 19:00:18.938: E/AndroidRuntime(4124): at android.os.Handler.dispatchMessage(Handler.java:92) 01-07 19:00:18.938: E/AndroidRuntime(4124): at android.os.Looper.loop(Looper.java:123) 01-07 19:00:18.938: E/AndroidRuntime(4124): at android.app.ActivityThread.main(ActivityThread.java:4627) 01-07 19:00:18.938: E/AndroidRuntime(4124): at java.lang.reflect.Method.invokeNative(Native Method) 01-07 19:00:18.938: E/AndroidRuntime(4124): at java.lang.reflect.Method.invoke(Method.java:521) 01-07 19:00:18.938: E/AndroidRuntime(4124): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 01-07 19:00:18.938: E/AndroidRuntime(4124): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 01-07 19:00:18.938: E/AndroidRuntime(4124): at dalvik.system.NativeStart.main(Native Method) 

Dans onPreExecute (), le FriendListFragment a l’identifiant = 0x7f0a0002. À l’intérieur du gestionnaire, le factice factice est créé avec id = 0x7f0a0004. Dans onPostExecute (), les deux identifiants sont nuls. Dans onPreExecute (), l’adresse de MyFragmentActivity est 45e38358. mais dans onPostExecute () c’est nul. Mais dans les deux méthodes, l’adresse de FragmentManager est 45e384a8. Je suppose que onPostExecute utilise un FragmentManager non valide. Mais pourquoi?

Vous devez effectuer la transaction dans un Handler comme suit:

 @Override protected void onPostExecute(Ssortingng result) { Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute"); new Handler().post(new Runnable() { public void run() { fm = getSupportFragmentManager(); ft = fm.beginTransaction(); ft.remove(dummyFragment); ft.commit(); } }); } 

Merci Oleg Vaskevich. Utiliser une WeakReference du FragmentActivity résolu le problème. Mon code ressemble maintenant à ceci:

 public class MyFragmentActivity extends FragmentActivity implements OnFriendAddedListener { private static WeakReference wrActivity = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); wrActivity = new WeakReference(this); ... private class onFriendAddedAsyncTask extends AsyncTask { @Override protected void onPreExecute() { FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); DummyFragment dummyFragment = DummyFragment.newInstance(); ft.add(R.id.dummy_fragment_layout, dummyFragment); ft.commit(); } @Override protected void onPostExecute(Ssortingng result) { final Activity activity = wrActivity.get(); if (activity != null && !activity.isFinishing()) { FragmentManager fm = activity.getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); DummyFragment dummyFragment = (DummyFragment) fm.findFragmentById(R.id.dummy_fragment_layout); ft.remove(dummyFragment); ft.commitAllowingStateLoss(); } } 

Je crois que la réponse correcte à cette question est la méthode suivante.

 public abstract int commitAllowingStateLoss () 

Comme commit () mais permet l’exécution de la validation après la sauvegarde de l’état d’une activité. Cela est dangereux car la validation peut être perdue si l’activité doit être restaurée ultérieurement à partir de son état. Elle ne doit donc être utilisée que dans les cas où l’état de l’interface utilisateur peut changer de manière inattendue pour l’utilisateur.

La description ci-dessus concerne cette méthode.

 protected void onSaveInstanceState(android.os.Bundle outState) 

Ce problème se produit précisément lorsque l’appareil se met en veille.

http://developer.android.com/reference/android/app/FragmentTransaction.html

Solution courte et fonctionnelle:

Suivez les étapes simples:

Étape 1 : Remplacez l’état onSaveInstanceState dans le fragment respectif. Et enlevez-en la méthode super.

 @Override public void onSaveInstanceState(Bundle outState) { } 

Étape 2 : utilisez CommitAllowingStateLoss(); au lieu de commit(); tout en fragmentant les opérations.

 fragmentTransaction.commitAllowingStateLoss(); 

Vérifiez si l’activité isFinishing() avant d’afficher le fragment.

Exemple:

 if(!isFinishing()) { FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); DummyFragment dummyFragment = DummyFragment.newInstance(); ft.add(R.id.dummy_fragment_layout, dummyFragment); ft.commitAllowingStateLoss(); } 

J’ai eu un problème similaire que j’ai corrigé en déplaçant un code de transaction de fragment de onResume() dans onStart() .

Pour être plus précis: mon application est un lanceur. Après avoir appuyé sur le bouton Android Home, l’utilisateur peut choisir un lanceur jusqu’à ce que sa décision soit mémorisée. Lorsque vous revenez en arrière (par exemple en tapotant sur la zone grisâtre), l’application s’est écrasée.

Peut-être que cela aide quelqu’un.

Cela m’est arrivé parce que j’invoquais commit() partir d’un sous-fragment qui était une activité qui fuyait. Il a gardé l’activité en tant que propriété et sur une activité de rotation, la variable n’a pas été mise à jour par onAttach(); J’essayais donc de valider la transaction sur l’activité zombie en la conservant (setRetainInstance(true);) fragment.

La raison de cette exception est la recréation de FragmentActivity lors de l’exécution d’ AsyncTask et l’access au précédent FragmentActivity détruit dans onPostExecute() après.

Le problème est d’obtenir une référence valide au nouveau FragmentActivity . Il n’y a pas de méthode pour cela ni getActivity() ni findById() ou quelque chose de similaire. Ce forum est plein de sujets correspondant à ce problème (par exemple, recherchez "Activity context in onPostExecute" ). Certaines d’entre elles décrivent des solutions de contournement (jusqu’à présent je n’en trouvais pas une bonne).

Peut-être que ce serait une meilleure solution pour utiliser un service dans mon but.

Pour ce que ça vaut J’ai eu cette erreur sur une application qui exécutait des services en arrière-plan. Sur l’un d’eux, une boîte de dialog de temporisation devait être affichée à l’utilisateur. Cette boîte de dialog était le problème à l’origine de cette erreur si l’application ne s’exécutait plus au premier plan.

Dans notre cas montrant que la boîte de dialog n’était pas utile lorsque l’application était en arrière-plan, nous avons simplement gardé une trace de cela (booléen marqué onPause en onResume) et n’affiche alors que la boîte de dialog

Solution 1: remplacez onSaveInstanceState() et supprimez le super appel qu’il onSaveInstanceState() .

 @Override public void onSaveInstanceState(Bundle outState) { } 

Solution 2: remplacez onSaveInstanceState() et supprimez votre fragment avant le super appel

 @Override public void onSaveInstanceState(Bundle outState) { // TODO: Add code to remove fragment here super.onSaveInstanceState(outState); } 

Ce problème se produit lorsqu’un processus tente de manipuler une activité dont onStop() a été appelé. Ce n’est pas nécessairement lié à la transaction de fragment mais aussi à d’autres méthodes comme onBackPressed ().

En plus d’AsyncTask, une autre source de ce problème est le mauvais placement de l’abonnement du motif de bus. En général, les abonnements Event Bus ou RxBus sont enregistrés lors des activités onCreate et désinscrits dans onDestroy. Si une nouvelle activité démarre et publie un événement intercepté par les abonnés de l’activité précédente, cette erreur peut se produire. Si cela se produit, une solution consiste à transférer l’enregistrement et la désinscription de l’abonnement vers onStart() et onStop() .

Il existe une solution alternative (PAS la meilleure solution) pour ce problème, mais fonctionne. En utilisant le drapeau, vous pouvez le gérer, comme ci-dessous

 /** * Flag to avoid "java.lang.IllegalStateException: Can not perform this action after * onSaveInstanceState". Avoid Fragment transaction until onRestoreInstanceState or onResume * gets called. */ private boolean isOnSaveInstanceStateCalled = false; @Override public void onRestoreInstanceState(final Bundle bundle) { ..... isOnSaveInstanceStateCalled = false; ..... } @Override public void onSaveInstanceState(final Bundle outState) { ..... isOnSaveInstanceStateCalled = true; ..... } @Override public void onResume() { super.onResume(); isOnSaveInstanceStateCalled = false; ..... } 

Et vous pouvez vérifier cette valeur boolean tout en effectuant une transaction fragmentée.

 private void fragmentReplace(Fragment fragment, Ssortingng fragmentTag){ if (!isOnSaveInstanceStateCalled) { getSupportFragmentManager() .beginTransaction() .replace(R.id.layout_container, fragment, fragmentTag) .commit(); } } 

Mon application a un fragment à charger en 3 secondes, mais lorsque l’écran de poing se prépare à afficher, j’appuie sur le bouton home et reprends-le, il affiche la même erreur, donc il modifie mon code et il s’est très bien passé:

 new Handler().post(new Runnable() { public void run() { if (saveIns == null) { mFragment = new Fragment_S1_loading(); getFragmentManager().beginTransaction() .replace(R.id.container, mFragment).commit(); } getActionBar().hide(); // Loading screen in 3 secs: mCountDownTimerLoading = new CountDownTimer(3000, 1000) { @Override public void onTick(long millisUntilFinished) { } @Override public void onFinish() { if (saveIns == null) {// TODO bug when start app and press home // button getFragmentManager() .beginTransaction() .replace(R.id.container, new Fragment_S2_sesstion1()).commitAllowingStateLoss(); } getActionBar().show(); } }.start(); } }); 

REMARQUE: ajoutez commitAllowingStateLoss () au lieu de commit ()

A partir de la version 24.0.0 de la bibliothèque de support, vous pouvez appeler la méthode FragmentTransaction.commitNow() qui valide cette transaction de manière synchrone au lieu d’appeler commit() suivi de executePendingTransactions()

Utilisez commitAllowingStateLoss() au lieu de commit() .

Lorsque vous utilisez commit() il peut lancer une exception si une perte d’état se produit, mais commitAllowingStateLoss() enregistre la transaction sans perte d’état, de sorte que will ne commitAllowingStateLoss() pas d’exception en cas de perte d’état.

IllegalStateException est rencontré si vous validez une transaction de fragment une fois que l’activité a perdu son état. L’activité n’est pas au premier plan. Cela se produit généralement lorsque vous essayez de valider un fragment dans AsyncTask ou après une requête réseau.

Pour éviter ce plantage, il vous suffit de retarder toute transaction de fragment jusqu’à ce que l’état d’activité soit restauré. Voici comment c’est fait

Déclarez deux variables booléennes privées

 public class MainActivity extends AppCompatActivity { //Boolean variable to mark if the transaction is safe private boolean isTransactionSafe; //Boolean variable to mark if there is any transaction pending private boolean isTransactionPending; 

Maintenant, dans onPostResume () et onPause, nous définissons et désactivons notre variable booléenne isTransactionSafe. L’idée est de marquer la sécurité des transactions uniquement lorsque l’activité est en avant-plan, de sorte qu’il n’y a aucune chance de dépassement.

 /* onPostResume is called only when the activity's state is completely restored. In this we will set our boolean variable to true. Indicating that transaction is safe now */ public void onPostResume(){ super.onPostResume(); isTransactionSafe=true; } /* onPause is called just before the activity moves to background and also before onSaveInstanceState. In this we will mark the transaction as unsafe */ public void onPause(){ super.onPause(); isTransactionSafe=false; } private void commitFragment(){ if(isTransactionSafe) { MyFragment myFragment = new MyFragment(); FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(R.id.frame, myFragment); fragmentTransaction.commit(); } } 

Ce que nous avons fait jusqu’ici sauvera de IllegalStateException, mais nos transactions seront perdues si elles sont effectuées après le passage de l’activité en arrière-plan, un peu comme commitAllowStateloss (). Pour aider avec cela, nous avons la variable booléenne isTransactionPending

 public void onPostResume(){ super.onPostResume(); isTransactionSafe=true; /* Here after the activity is restored we check if there is any transaction pending from the last restoration */ if (isTransactionPending) { commitFragment(); } } private void commitFragment(){ if(isTransactionSafe) { MyFragment myFragment = new MyFragment(); FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.add(R.id.frame, myFragment); fragmentTransaction.commit(); isTransactionPending=false; }else { /* If any transaction is not done because the activity is in background. We set the isTransactionPending variable to true so that we can pick this up when we come back to foreground */ isTransactionPending=true; } } 

Cet article explique en détail pourquoi cette exception est rencontrée et compare différentes méthodes pour le résoudre. Hautement recommandé

J’ai eu la même exception et j’ai essayé beaucoup d’extraits que j’ai trouvés ici dans cette discussion de stackoverflow, mais aucun fragment n’a fonctionné pour moi.

Mais j’ai pu résoudre tous les problèmes, je partagerai avec vous les solutions:

  • Dans une première partie: j’ai essayé d’afficher un DialogFragment sur une activité mais à partir d’une autre classe Java. Ensuite, en vérifiant l’atsortingbut de cette instance, j’ai trouvé que c’était une ancienne instance de l’activité, ce n’était pas l’activité en cours d’exécution. [Plus précisément, j’utilisais socket.io et j’ai oublié de faire un socket.off (“example”, exemple) … donc il est attaché à une ancienne instance de l’activité. ]

  • Dans une deuxième partie: J’essayais de montrer un DialogFragment dans une activité quand je reviens avec une intention, mais quand j’ai vérifié mes journaux, j’ai vu que quand il essayait de montrer le fragment, l’activité n’était toujours pas dans la méthode onStart , il a donc planté l’application car elle n’a pas trouvé la classe Activity pour afficher le fragment.

Quelques astuces: vérifiez avec certains atsortingbuts si vous n’utilisez pas une ancienne instance de votre activité avec laquelle vous essayez d’afficher votre fragment, ou vérifiez le cycle de vie de votre activité avant d’afficher votre fragment et assurez-vous d’être dans onStart ou onResume avant de l’afficher .

J’espère que ces explications vous aideront.