Java.lang.IllegalStateException: не удается выполнить это действие после onSaveInstanceState с помощью DialogFragment

Я столкнулся с проблемой с DialogFragment / getSupportFragmentManager / Android версии 4.x

01-10 19:46:48.228: E/AndroidRuntime(9879): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 01-10 19:46:48.228: E/AndroidRuntime(9879): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1314) 01-10 19:46:48.228: E/AndroidRuntime(9879): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1325) 01-10 19:46:48.228: E/AndroidRuntime(9879): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:548) 01-10 19:46:48.228: E/AndroidRuntime(9879): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:532) 01-10 19:46:48.228: E/AndroidRuntime(9879): at android.support.v4.app.DialogFragment.show(DialogFragment.java:127) 01-10 19:46:48.228: E/AndroidRuntime(9879): at com.v1.mypck.TermsAndConditions.showDialog(TermsAndConditions.java:256) 01-10 19:46:48.228: E/AndroidRuntime(9879): at com.v1.mypck.TermsAndConditions.handleMessage(TermsAndConditions.java:62) 01-10 19:46:48.228: E/AndroidRuntime(9879): at com.v1.mypck.TermsAndConditions$IncomingHandler.handleMessage(TermsAndConditions.java:53) 01-10 19:46:48.228: E/AndroidRuntime(9879): at android.os.Handler.dispatchMessage(Handler.java:99) 01-10 19:46:48.228: E/AndroidRuntime(9879): at android.os.Looper.loop(Looper.java:137) 01-10 19:46:48.228: E/AndroidRuntime(9879): at android.app.ActivityThread.main(ActivityThread.java:4441) 01-10 19:46:48.228: E/AndroidRuntime(9879): at java.lang.reflect.Method.invokeNative(Native Method) 01-10 19:46:48.228: E/AndroidRuntime(9879): at java.lang.reflect.Method.invoke(Method.java:511) 01-10 19:46:48.228: E/AndroidRuntime(9879): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 01-10 19:46:48.228: E/AndroidRuntime(9879): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 01-10 19:46:48.228: E/AndroidRuntime(9879): at dalvik.system.NativeStart.main(Native Method) 

В нижеприведенном коде, когда я нажимаю его, он пытается завершить текущую активность и вернуться к предыдущему действию, которое выдает над ошибкой.

Код работает хорошо в старой версии (до 4.x).

Может ли кто-нибудь вести меня в правильном направлении.

 public class TermsAndConditions extends SherlockFragmentActivity implements LoaderManager.LoaderCallbacks<JSONObject>{ static final String TAG = "TermsAndConditions"; private static int titleResource; private static int messageResource; private IncomingHandler handler = null; private static final int SHOW_NETWORK_DIALOG = 3; static class IncomingHandler extends Handler { private final WeakReference<TermsAndConditions> mTarget; IncomingHandler(TermsAndConditions target) { mTarget = new WeakReference<TermsAndConditions>(target); } @Override public void handleMessage(Message msg) { TermsAndConditions target = mTarget.get(); if (target != null) { target.handleMessage(msg); } } } public void handleMessage(Message msg) { switch (msg.what) { case SHOW_NETWORK_DIALOG: titleResource = R.string.msg_alert_no_network_title; messageResource = R.string.msg_alert_no_network_message; showDialog(); break; } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.web_view); getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportLoaderManager().initLoader(0, null, this); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: finish(); return true; default: return super.onOptionsItemSelected(item); } } private void loadViewData() { //Logic to load content. } @Override public Loader<JSONObject> onCreateLoader(int arg0, Bundle arg1) { if (handler == null){ handler = new IncomingHandler(TermsAndConditions.this); } return new JsonLoader(this); } @Override public void onLoadFinished(Loader<JSONObject> arg0, JSONObject jsonData) { if(jsonDataObject==null || jsonDataObject.length()==0) { handler.sendEmptyMessage(SHOW_NETWORK_DIALOG); } else { loadViewData(); } } @Override public void onLoaderReset(Loader<JSONObject> arg0) { if(jsonDataObject==null || jsonDataObject.length()==0) { handler.sendEmptyMessage(SHOW_NETWORK_DIALOG); } else { loadViewData(); } } public static class JsonLoader extends AsyncTaskLoader<JSONObject> { public JsonLoader(Context context) { super(context); } @Override protected void onStartLoading() { if (jsonDataObject != null) { deliverResult(jsonDataObject); } if (takeContentChanged() || jsonDataObject == null) { forceLoad(); } } @Override public JSONObject loadInBackground() { try { return response.getJSONObject("result"); } catch (JSONException e) { return null; } catch (Throwable e) { return null; } } @Override public void deliverResult(JSONObject newJsonData) { if (isReset()) { if (jsonDataObject != null) { onReleaseResources(jsonDataObject); } } JSONObject oldData = jsonDataObject; jsonDataObject = newJsonData; if (isStarted()) { super.deliverResult(jsonDataObject); } if (oldData != null) { onReleaseResources(oldData); } } @Override protected void onStopLoading() { cancelLoad(); } @Override public void onCanceled(JSONObject jsonData) { super.onCanceled(jsonData); onReleaseResources(jsonData); } @Override protected void onReset() { super.onReset(); onStopLoading(); if (jsonDataObject != null) { onReleaseResources(jsonDataObject); jsonDataObject = null; } } protected void onReleaseResources(JSONObject jsonData) { jsonData = null; } } public static class MyAlertDialogFragment extends DialogFragment { public static MyAlertDialogFragment newInstance(int title) { MyAlertDialogFragment frag = new MyAlertDialogFragment(); Bundle args = new Bundle(); args.putInt("title", title); frag.setArguments(args); return frag; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { int title = getArguments().getInt("title"); return new AlertDialog.Builder(getActivity()) .setTitle(title) .setMessage(messageResource) .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } } ) .create(); } } public void showDialog() { DialogFragment newFragment = MyAlertDialogFragment.newInstance(titleResource); newFragment.show(getSupportFragmentManager(), "my_dialog"); } } 

Solutions Collecting From Web of "Java.lang.IllegalStateException: не удается выполнить это действие после onSaveInstanceState с помощью DialogFragment"

Вот ответ в другом потоке:

Действия в onActivityResult и "Ошибка Не удается выполнить это действие после onSaveInstanceState"

также здесь:

Обновление моего фрагмента не работает, как я думал, он должен

Это пример решения этой проблемы:

 DialogFragment loadingDialog = createDialog(); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.add(loadingDialog, "loading"); transaction.commitAllowingStateLoss(); 

У меня такая же проблема, и я изменил код как ниже

 newFragment.show(transactionFragment, "dialog"); 

чтобы:

 transactionFragment.add(android.R.id.content, newFragment).addToBackStack(null).commitAllowingStateLoss(); 

Полный код работает хорошо для меня, как рев, надеюсь, что помощь

 FragmentTransaction transactionFragment = getActivity().getSupportFragmentManager().beginTransaction(); DialogPageListFragment newFragment = new DialogPageListFragment(); transactionFragment.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); newFragment.setArguments(extras); transactionFragment.add(android.R.id.content, newFragment).addToBackStack(null).commitAllowingStateLoss(); 

Вероятно, обработчик, реагирующий на HandleMessage, связан с разрушенным действием.

Т.е.: если вы поворачиваете экран, то старое уничтоженное действие будет обрабатывать сообщение, тогда вы вызовете showDialog, и будет выведено исключение:

Вы создаете диалог после того, как старое разрушенное действие вызвало его onSaveInstanceState.

Попробуйте заменить обратный вызов новым созданным действием, чтобы убедиться, что вы создаете диалог всегда в активном действии.


Если вы не вращаетесь, установите флаг onSaveInstance как «сохранение» и отключите его onRestoreInstance. В методе handleMessage, если флаг «Сохранить» включен, не показывайте диалоговое окно, просто включите другой флаг, указывающий, что диалог должен быть создан на onResume. Затем в методе onResume проверьте, если в середине этого процесса вы должны создать диалог, если да, покажите его по методу onResume.

 fragmentView.post(() -> { FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction(); YourDialog yourDialog = YourDialog.newInstance(); yourDialog.show(ft, "text_data"); }); 

Цель метода post () заключается в том, чтобы ждать, пока закончится действие операции или фрагмента onResume (). Он работает, если вы хотите показать DialogFragment из Fragment., Fe, когда вы хотите показать свое диалоговое окно после отклонения системного диалога.

Я столкнулся с той же проблемой, когда post delaying Runnables handler.postDelayed (Runnable runnable, long delayed).

Я решил проблему таким образом:

  1. В onSaveInstanceState я отменяю отложенные задачи
  2. В onRestoreInstanceState я воссоздаю задачу, если были замедленные задачи, когда активность была уничтожена

OnPostResume () использовать метод post resume для выполнения вашей работы. Я думаю, что вы вызываете метод show dialog в onRestart или onResume, поэтому избегайте его и используйте onPostResume (), чтобы показать свое диалоговое окно.

Вы можете проверить, является ли текущая активность isActive () и только в этом случае начать транзакцию фрагмента DialogFragment. У меня была аналогичная проблема, и эта проверка решила мое дело.

Оно работает:

 CheckinSuccessDialog dialog = new CheckinSuccessDialog(); //dialog.show(getSupportFragmentManager(), null); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.add(dialog, null); ft.commitAllowingStateLoss(); 

Но все же плохо, потому что получена ошибка «Активность была уничтожена»

  ava.lang.IllegalStateException: Activity has been destroyed fragmentTransaction.commitAllowingStateLoss(); 

Поэтому мое решение добавляет проверку, if (!isFinishing()&&!isDestroyed())

 CheckinSuccessDialog fragment = CheckinSuccessDialog.newInstance(); if (fragment instanceof DialogFragment) { DialogFragment dialog = (DialogFragment) fragment; if (!dialog.isAdded()) { fragmentTransaction.add(dialog, CheckinSuccessDialog.class.getName()); if (!isFinishing()&&!isDestroyed()) { fragmentTransaction.commitAllowingStateLoss(); } } 

На увольнении:

  FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); Fragment fragment = getSupportFragmentManager().findFragmentByTag(CheckinSuccessDialog.class.getName()); if (fragment != null && fragment instanceof DialogFragment) { DialogFragment dialog = (DialogFragment) fragment; dialog.dismiss(); if (!isFinishing()&&!isDestroyed()) { fragmentTransaction.commitAllowingStateLoss(); } } 

В действии перед показом диалога вы можете сделать что-то вроде этого

 getSupportFragmentManager().executePendingTransactions(); 

Это сработало для меня.