J'utilise la bibliothèque d'assistance de mon application. Dans mon FragmentActivity, j'utilise une 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. Veuillez jeter un œil aux détails:
private class onFriendAddedAsyncTask extends AsyncTask<String, Void, String> {
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(String result) {
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/onPostExecute");
ft = fm.beginTransaction();
ft.remove(dummyFragment);
ft.commit();
}
@Override
protected String doInBackground(String... name) {
Log.v("MyFragmentActivity", "onFriendAddedAsyncTask/doInBackground");
...
}
Je reçois 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 threads sur des problèmes similaires, la raison semble être que la méthode onPostExecute est appelée avant que la méthode onResume () ne soit appelée. 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<Cursor> {
@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(String name) {
name = name.trim();
if (name.length() > 0) {
new onFriendAddedAsyncTask().execute(name);
}
}
Lorsque vous utilisez 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)
J'obtiens le même IllegalStateExeption lorsque j'implémente l'AsynTask comme suit, car la méthode findFragmentById () renvoie un pointeur nul.
private class onFriendAddedAsyncTask extends AsyncTask<String, Void, String> {
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(String 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();
}
Dans l'étape suivante, j'utilise un gestionnaire pour l'ajout et la suppression du DummyFragment. De plus, j'ai ajouté une sortie de débogage supplémentaire.
private class onFriendAddedAsyncTask extends AsyncTask<String, Void, String> {
@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(String 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 reçois 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 (), FriendListFragment a l'id = 0x7f0a0002. À l'intérieur du gestionnaire, le DummyFragment est créé avec id = 0x7f0a0004. Dans onPostExecute (), les deux ID sont nuls. Dans onPreExecute (), l'adresse de MyFragmentActivity est 45e38358. mais dans onPostExecute (), il est nul. Mais dans les deux méthodes, l'adresse FragmentManager est 45e384a8. Je suppose que onPostExecute utilise un FragmentManager invalide. Mais pourquoi?
Réponses:
Vous devez effectuer la transaction
Handler
comme suit:la source
private static WeakReference<FragmentActivity> mActivity = null;
WeakReference
vous empêche de divulguer l'activité ... vous devez appelermActivity.get()
pour obtenir réellement l'instance, et elle sera nulle si l'activité a été détruite. Pour le mettre à jour, vous devrez écriremActivity = new WeakReference<FragmentActivity>(this);
- il y a un bon endroitonCreate()
- qui mettra à jour la référence.Merci Oleg Vaskevich. L'utilisation d'un
WeakReference
des aFragmentActivity
résolu le problème. Mon code ressemble maintenant à ceci:la source
MyFragmentActivity mActivity = this ?
With out static & WeakReferenceJe pense que la bonne réponse à cette question est la méthode suivante.
La description ci-dessus concerne ce procédé.
Ce problème se produit précisément lorsque l'appareil se met en veille.
http://developer.android.com/reference/android/app/FragmentTransaction.html
la source
Solution courte et fonctionnelle:
Suivez des étapes simples:
Étape 1 : Remplacer l'
onSaveInstanceState
état dans le fragment respectif. Et supprimez-en la super méthode.Étape 2 : Utilisez
CommitAllowingStateLoss();
au lieu d'commit();
opérations de fragment while.la source
Vérifiez si l'activité
isFinishing()
avant d'afficher le fragment.Exemple:
la source
J'ai eu un problème similaire que j'ai résolu en déplaçant un fragment de code de transaction de
onResume()
versonStart()
.Pour être plus précis: mon application est un lanceur. Après avoir appuyé sur le bouton Accueil d'Android, l'utilisateur peut choisir un lanceur jusqu'à ce que sa décision soit mémorisée. En retournant "en arrière" à ce stade (par exemple en tapant dans la zone grisâtre), l'application s'est plantée.
Peut-être que cela aide quelqu'un.
la source
Utilisez à la
commitAllowingStateLoss()
place decommit()
.lorsque vous l'utilisez,
commit()
il peut lever une exception en cas de perte d'état, maiscommitAllowingStateLoss()
enregistre la transaction sans perte d'état, de sorte que cela ne lève pas d'exception en cas de perte d'état.la source
Cela m'est arrivé, car
commit()
j'invoquais à partir d'un sous-fragment qui fuyait une activité. Il a gardé l'activité en tant que propriété et sur une variable d'activité de rotation n'a pas été mise à jour paronAttach();
Donc j'essayais de valider la transaction sur l'activité zombie par(setRetainInstance(true);)
fragment conservé .la source
La raison de l'exception est la recréation du
FragmentActivity
pendant l'exécution duAsyncTask
et l'accès au précédent, détruitFragmentActivity
par laonPostExecute()
suite.Le problème est d'obtenir une référence valide au nouveau
FragmentActivity
. Il n'y a pas de méthode pour cela nigetActivity()
nifindById()
ni quelque chose de similaire. Ce forum est plein de fils en fonction de ce problème (par exemple, recherche de"Activity context in onPostExecute"
). Certains d'entre eux décrivent des solutions de contournement (jusqu'à présent, je n'en ai pas trouvé une bonne).Peut-être que ce serait une meilleure solution d'utiliser un service pour mon objectif.
la source
Il existe une solution alternative (PAS la meilleure solution) pour ce problème, mais cela fonctionne. En utilisant le drapeau, vous pouvez le gérer, comme ci-dessous
Et vous pouvez vérifier cette
boolean
valeur lors de la transaction de fragment.la source
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 dialogue de temporisation a dû être présentée à l'utilisateur. Cette boîte de dialogue était à l'origine de cette erreur si l'application ne fonctionnait plus au premier plan.
Dans notre cas, afficher la boîte de dialogue n'était pas utile lorsque l'application était en arrière-plan, nous avons donc juste gardé une trace de cela (booléen marqué onPause en onResume), puis n'afficher la boîte de dialogue que lorsque l'application est réellement visible par l'utilisateur.
la source
Solution 1: remplacez
onSaveInstanceState()
et supprimez le super appel qu'il contient.Solution 2: remplacez
onSaveInstanceState()
et supprimez votre fragment avant le super appella source
Ce problème se produit lorsqu'un processus tente de manipuler une activité qui
onStop()
a été appelée. Ce n'est pas nécessairement lié à la transaction fragmentée 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 au modèle de bus. Habituellement, l'abonnement Event Bus ou RxBus est enregistré pendant le onCreate d'Activité et désenregistré dans onDestroy. Si une nouvelle activité démarre et publie un événement intercepté par les abonnés de l'activité précédente, elle peut produire cette erreur. Si cela se produit, une solution consiste à déplacer l'inscription et la désinscription de l'abonnement vers
onStart()
etonStop()
.la source
Cela a résolu mon problème: Code Kotlin:
En quoi est
commitAllowingStateLoss()
-ce différent decommit()
?Selon la documentation:
Like
commit()
mais autorise l'exécution du commit après l'enregistrement de l'état d'une activité. https://developer.android.com/reference/android/app/FragmentTransaction#commitAllowingStateLoss ()PS: vous pouvez afficher les boîtes de dialogue de fragments ou charger des fragments par cette méthode. Applicable pour les deux.
la source
Mon application a un fragment à charger en 3 secondes, mais lorsque le premier écran se prépare à s'afficher, j'appuie sur le bouton d'accueil et je recommence à l'exécuter, il affiche la même erreur, donc il modifie mon code et il s'est déroulé très bien:
REMARQUE: ajoutez commitAllowingStateLoss () au lieu de commit ()
la source
À partir de la version 24.0.0 de la bibliothèque de support, vous pouvez appeler la
FragmentTransaction.commitNow()
méthode qui valide cette transaction de manière synchrone au lieu d'appelercommit()
suivie deexecutePendingTransactions()
la source
IllegalStateException est rencontré si vous validez une transaction de fragment après 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 demande réseau.
Pour éviter ce crash, il vous suffit de retarder toute transaction de fragment jusqu'à ce que l'état d'activité soit restauré. Voici comment cela se fait
Déclarez deux variables booléennes privées
Maintenant, dans onPostResume () et onPause, nous définissons et annulons notre variable booléenne isTransactionSafe. L'idée est de marquer la transaction comme sûre uniquement lorsque l'activité est au premier plan afin qu'il n'y ait aucune chance de perte d'état.
Ce que nous avons fait jusqu'à présent sauvera de IllegalStateException mais nos transactions seront perdues si elles sont effectuées après que l'activité passe en arrière-plan, un peu comme commitAllowStateloss (). Pour vous aider, nous avons la variable booléenne isTransactionPending
Cet article explique en détail pourquoi cette exception est rencontrée et compare différentes méthodes pour la résoudre. Hautement recommandé
la source
J'ai eu la même exception et j'ai essayé de nombreux extraits de code que j'ai trouvés ici dans cette discussion stackoverflow, mais aucun extrait 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'attribut de cette instance, j'ai trouvé qu'il s'agissait d'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 ("exemple", exemple) ... donc il s'est attaché à une ancienne instance de l'activité. ]
Dans une deuxième partie: j'essayais de montrer un DialogFragment dans une activité quand j'y reviens avec une intention, mais quand j'ai vérifié mes journaux, j'ai vu que quand il a essayé de montrer le fragment, l'activité n'était toujours pas dans la méthode onStart , il a donc planté l'application car il n'a pas trouvé la classe Activity pour afficher le fragment dessus.
Quelques conseils: vérifiez avec certains attributs 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 que vous êtes dans onStart ou onResume avant de l'afficher .
J'espère que ces explications vous aideront.
la source