Ich verwende die Support-Bibliothek für meine App. In meiner FragmentActivity verwende ich eine AsyncTask zum Herunterladen von Daten aus dem Internet. In der onPreExecute () -Methode füge ich ein Fragment hinzu und in der onPostExecute () -Methode entferne ich es erneut. Wenn die Ausrichtung dazwischen geändert wird, erhalte ich die oben genannte Ausnahme. Bitte schauen Sie sich die Details an:
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");
...
}
Ich erhalte folgenden 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)
In anderen Threads zu ähnlichen Problemen scheint der Grund darin zu liegen, dass die onPostExecute-Methode aufgerufen wird, bevor die onResume () -Methode aufgerufen wird. Aber ich bekomme die Ausnahme, obwohl onResume () vorher aufgerufen wurde.
Weiß jemand, was los ist?
Die Aktivität sieht folgendermaßen aus:
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);
}
}
Bei Verwendung von commitAllowingStateLoss () tritt folgende Ausnahme auf:
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)
Ich erhalte dieselbe IllegalStateExeption, wenn ich die AsynTask wie folgt implementiere, da die findFragmentById () -Methode einen Nullzeiger zurückgibt.
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();
}
Im nächsten Schritt verwende ich einen Handler zum Hinzufügen und Entfernen des DummyFragments. Zusätzlich habe ich einige weitere Debug-Ausgaben hinzugefügt.
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();
}
});
Ich erhalte folgenden 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)
In onPreExecute () hat das FriendListFragment die ID = 0x7f0a0002. Im Handler wird das DummyFragment mit der ID = 0x7f0a0004 erstellt. In onPostExecute () sind beide IDs null. In onPreExecute () lautet die Adresse von MyFragmentActivity 45e38358. aber in onPostExecute () ist es null. Bei beiden Methoden lautet die FragmentManager-Adresse jedoch 45e384a8. Ich denke, onPostExecute verwendet einen ungültigen FragmentManager. Aber wieso?
Antworten:
Sie sollten die Transaktion
Handler
wie folgt ausführen:quelle
private static WeakReference<FragmentActivity> mActivity = null;
WeakReference
verhindert, dass Sie die Aktivität verlieren ... Sie müssen aufrufenmActivity.get()
, um die Instanz tatsächlich zu erhalten, und sie ist null, wenn die Aktivität zerstört wurde. Um es zu aktualisieren, müssen Sie schreibenmActivity = new WeakReference<FragmentActivity>(this);
- ein guter Ort ist inonCreate()
-, der die Referenz aktualisiert.Danke Oleg Vaskevich. Mit einem
WeakReference
derFragmentActivity
das Problem gelöst. Mein Code sieht jetzt wie folgt aus:quelle
MyFragmentActivity mActivity = this ?
mit aus statischem & WeakReferenceIch glaube, die richtige Antwort auf diese Frage ist die folgende Methode.
Die obige Beschreibung bezieht sich auf dieses Verfahren.
Dieses Problem tritt genau dann auf, wenn das Gerät in den Ruhezustand wechselt.
http://developer.android.com/reference/android/app/FragmentTransaction.html
quelle
Kurze und funktionierende Lösung:
Befolgen Sie einfache Schritte:
Schritt 1 : Überschreiben Sie den
onSaveInstanceState
Status im jeweiligen Fragment. Und entfernen Sie die Super-Methode daraus.Schritt 2 : Verwenden Sie
CommitAllowingStateLoss();
anstelle voncommit();
while-Fragmentoperationen.quelle
Überprüfen Sie die Aktivität,
isFinishing()
bevor Sie das Fragment anzeigen.Beispiel:
quelle
Ich hatte ein ähnliches Problem, das ich behoben habe, indem ich einen Fragmenttransaktionscode von
onResume()
in verschoben habeonStart()
.Genauer gesagt: Meine App ist ein Launcher. Nach dem Drücken der Android Home-Taste kann der Benutzer einen Launcher auswählen, bis seine Entscheidung gespeichert ist. Wenn Sie an dieser Stelle "zurück" gehen (z. B. durch Tippen auf den grauen Bereich), stürzte die App ab.
Vielleicht hilft das jemandem.
quelle
Verwenden Sie
commitAllowingStateLoss()
anstelle voncommit()
.Wenn Sie
commit()
es verwenden, kann es eine Ausnahme auslösen, wenn ein Statusverlust auftritt, aber einecommitAllowingStateLoss()
Transaktion ohne Statusverlust speichern, sodass keine Ausnahme ausgelöst wird, wenn ein Statusverlust auftritt.quelle
Das passierte für mich, weil ich mich auf ein
commit()
Subfragment berief, das eine undichte Aktivität aufwies. Die Aktivität wurde als Eigenschaft beibehalten, und eine Rotationsaktivitätsvariable wurde von nicht aktualisiert.onAttach();
Daher habe ich versucht, eine Transaktion für die Zombie-Aktivität durch ein beibehaltenes(setRetainInstance(true);)
Fragment festzuschreiben.quelle
Der Grund für die Ausnahme ist die Neuschöpfung der
FragmentActivity
während der Laufzeit desAsyncTask
und der Zugriff auf die vorherigen, zerstörtFragmentActivity
inonPostExecute()
danach.Das Problem besteht darin, einen gültigen Verweis auf das Neue zu erhalten
FragmentActivity
. Es gibt weder dafürgetActivity()
noch fürfindById()
etwas Ähnliches eine Methode . Dieses Forum ist voll von Threads zu diesem Thema (zB Suche nach"Activity context in onPostExecute"
). Einige von ihnen beschreiben Problemumgehungen (bis jetzt habe ich keine gute gefunden).Vielleicht wäre es eine bessere Lösung, einen Dienst für meinen Zweck zu nutzen.
quelle
Es gibt eine alternative Lösung (NICHT die beste Lösung) für dieses Problem, die jedoch funktioniert. Mit flag können Sie damit umgehen, wie unten
Und Sie können diesen
boolean
Wert überprüfen , während Sie eine Fragmenttransaktion durchführen.quelle
Für das, was es wert ist; Ich hatte diesen Fehler bei einer App, auf der Dienste im Hintergrund ausgeführt wurden. Auf einem von ihnen musste dem Benutzer ein Timeout-Dialog angezeigt werden. Dieser Dialog war das Problem, das diesen Fehler verursachte, wenn die App nicht mehr im Vordergrund lief.
In unserem Fall war das Anzeigen des Dialogfelds nicht hilfreich, wenn sich die App im Hintergrund befand. Wir haben dies nur verfolgt (boolesches Kennzeichen onPause en onResume) und das Dialogfeld dann nur angezeigt, wenn die App für den Benutzer tatsächlich sichtbar ist.
quelle
Lösung 1: Überschreiben
onSaveInstanceState()
und entfernen Sie den darin enthaltenen Superanruf.Lösung 2: Überschreiben
onSaveInstanceState()
und entfernen Sie Ihr Fragment vor dem Superaufrufquelle
Dieses Problem tritt auf, wenn ein Prozess versucht, eine Aktivität zu manipulieren, deren
onStop()
aufgerufene . Es ist nicht unbedingt an Fragmenttransaktionen gebunden, sondern auch an andere Methoden wie onBackPressed ().Neben AsyncTask ist eine weitere Ursache für ein solches Problem die Fehlplatzierung des Abonnements des Busmusters. Normalerweise wird das Abonnement von Event Bus oder RxBus während onCreate von Activity registriert und in onDestroy abgemeldet. Wenn eine neue Aktivität ein Ereignis startet und veröffentlicht, das von Abonnenten der vorherigen Aktivität abgefangen wurde, kann dies zu diesem Fehler führen. In diesem Fall besteht eine Lösung darin, die Abonnementregistrierung und -abmeldung nach
onStart()
und zu verschiebenonStop()
.quelle
Dies löste mein Problem: Kotlin Code:
Wie
commitAllowingStateLoss()
ist anders alscommit()
?Gemäß Dokumentation:
Wie,
commit()
aber ermöglicht das Ausführen des Commits, nachdem der Status einer Aktivität gespeichert wurde. https://developer.android.com/reference/android/app/FragmentTransaction#commitAllowingStateLoss ()PS: Mit dieser Methode können Sie Fragmentdialoge anzeigen oder Fragmente laden. Gilt für beide.
quelle
Meine App hat ein Fragment, das in 3 Sekunden geladen werden muss. Wenn sich der erste Bildschirm auf die Anzeige vorbereitet, drücke ich die Home-Taste und setze die Ausführung fort. Es wird der gleiche Fehler angezeigt. Daher wird mein Code bearbeitet und es läuft sehr reibungslos:
HINWEIS: Fügen Sie commitAllowingStateLoss () anstelle von commit () hinzu.
quelle
Ab der Support Library-Version 24.0.0 können Sie eine
FragmentTransaction.commitNow()
Methode aufrufen , die diese Transaktion synchron festschreibt, anstatt sie aufzurufen,commit()
gefolgt vonexecutePendingTransactions()
quelle
IllegalStateException tritt auf, wenn Sie eine Fragmenttransaktion festschreiben, nachdem die Aktivität ihren Status verloren hat. Die Aktivität steht nicht im Vordergrund. Dies tritt häufig auf, wenn Sie versuchen, ein Fragment in AsyncTask oder nach einer Netzwerkanforderung festzuschreiben.
Um diesen Absturz zu vermeiden, müssen Sie lediglich alle Fragmenttransaktionen verzögern, bis der Aktivitätsstatus wiederhergestellt ist. Das Folgende ist, wie es gemacht wird
Deklarieren Sie zwei private boolesche Variablen
Jetzt setzen und deaktivieren wir in onPostResume () und onPause unsere boolesche Variable isTransactionSafe. Die Idee ist, die Transaktion nur dann als sicher zu markieren, wenn die Aktivität im Vordergrund steht, sodass keine Gefahr eines Statusverlusts besteht.
Was wir bisher getan haben, wird vor IllegalStateException gespeichert, aber unsere Transaktionen gehen verloren, wenn sie ausgeführt werden, nachdem die Aktivität in den Hintergrund verschoben wurde, ähnlich wie commitAllowStateloss (). Um dies zu unterstützen, haben wir die boolesche Variable isTransactionPending
In diesem Artikel wird ausführlich erläutert, warum diese Ausnahme auftritt, und es werden verschiedene Methoden zum Beheben dieser Ausnahme verglichen. Sehr empfehlenswert
quelle
Ich hatte die gleiche Ausnahme und habe viele Snippets ausprobiert, die ich hier in dieser Stackoverflow-Diskussion gefunden habe, aber für mich haben keine Snippets funktioniert.
Aber ich konnte alle Probleme lösen, ich werde Ihnen die Lösungen mitteilen:
In einem ersten Teil: Ich habe versucht, ein DialogFragment für eine Aktivität anzuzeigen, aber von einer anderen Java-Klasse. Durch Überprüfen des Attributs dieser Instanz stellte ich fest, dass es sich um eine alte Instanz der Aktivität handelte und nicht um die aktuell ausgeführte Aktivität. [Genauer gesagt habe ich socket.io verwendet und vergessen, ein socket.off ("Beispiel", Beispiel) auszuführen ... also wurde es an eine alte Instanz der Aktivität angehängt. ]]
In einem zweiten Teil: Ich habe versucht, ein DialogFragment in einer Aktivität anzuzeigen, als ich mit Absicht darauf zurückkam. Als ich jedoch meine Protokolle überprüfte, stellte ich fest, dass sich die Aktivität beim Versuch, das Fragment anzuzeigen, immer noch nicht in der onStart-Methode befand Daher stürzte die App ab, weil die Aktivitätsklasse zum Anzeigen des Fragments nicht gefunden wurde.
Einige Tipps: Überprüfen Sie anhand einiger Attribute, ob Sie keine alte Instanz Ihrer Aktivität verwenden, mit der Sie Ihr Fragment anzeigen möchten, oder überprüfen Sie Ihren Aktivitätslebenszyklus, bevor Sie Ihr Fragment anzeigen, und stellen Sie sicher, dass Sie sich in onStart oder onResume befinden, bevor Sie es anzeigen .
Ich hoffe, diese Erklärungen werden Ihnen helfen.
quelle