Фиксация FragmentTransaction в OnClick «IllegalStateException: невозможно выполнить это действие после onSaveInstanceState»

У меня есть приложение на рынке, и я получаю следующее исключение:

Fatal Exception: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
   at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1343)
   at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1361)
   at android.app.BackStackRecord.commitInternal(BackStackRecord.java:729)
   at android.app.BackStackRecord.commit(BackStackRecord.java:705)
   at com.mysupercoolapp.ui.fragments.ResultFragment$2.onItemClick(ResultFragment.java:139)
   at android.widget.AdapterView.performItemClick(AdapterView.java:339)
   at android.widget.AbsListView.performItemClick(AbsListView.java:1544)
   at android.widget.AbsListView$PerformClick.run(AbsListView.java:3721)
   at android.widget.AbsListView$3.run(AbsListView.java:5660)
   at android.os.Handler.handleCallback(Handler.java:739)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:145)
   at android.app.ActivityThread.main(ActivityThread.java:6837)
   at java.lang.reflect.Method.invoke(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:372)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

Я уже прочитал большинство тем по этой проблеме, но я не знаю, что я делаю неправильно в своем коде. Я не заменяю фрагмент в методе onResume. Я также не кэширую экземпляр FragmentTransaction. Я заменяю фрагмент, когда пользователь щелкает элемент в ListView.

Рабочий процесс кода моего фрагмента следующий

OnCreateView> выполняет AsyncTask для загрузки некоторых элементов из базы данных> onPostExecute вызывает метод, который устанавливает адаптер для ListView и добавляет OnItemClickListener, поэтому, когда пользователь нажимает элемент в ListView, он открывает элемент в другом фрагменте.

Вот код для него:

@Override
protected void onPostExecute(ResultAdapter adapter) {
     // post execute in AsyncTask
     setListAdapter(adapter);
}

public void setListAdapter(final ResultAdapter adapter) {
    if (adapter != null && isAdded()) {
        resultList.setAdapter(adapter);
        resultList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                final FragmentTransaction ft = getFragmentManager().beginTransaction();
                SomeFragment fragment = new SomeFragment();
                ft.replace(R.id.content_frame, fragment, "main_fragment");
                ft.addToBackStack(null);
                ft.commit();
            }
        });
        adapter.notifyDataSetChanged();
    }
}

Есть ли лучшее решение, чем вызов commitAllowingStateLoss() или переопределение onSaveInstanceState()?

P.S.: я ориентируюсь на API > 14 и использую стандартный пакет android.app.FragmentTransaction.


comment
Опубликуйте свой код onSavedInstanceState().   -  person Tomislav Turcic    schedule 07.11.2015


Ответы (1)


Эта проблема возникает при вызове onPostExecute() при свернутом приложении, особенно при вызове onPostExecute() после вызова метода onSaveInstanceState() действия.

Если вы беспокоитесь о потере состояния, то я предлагаю вам отменить AsyncTask, когда пользователь свернул приложение (вероятно, в методе onStop()). Затем в своем onPostExecute() вызовите setListAdapter(adapter) только в том случае, если AsyncTask не отменен. Это гарантирует, что вы не установите адаптер после вызова onSaveInstanceState().

Дополнительная информация о том, как это сделать, находится здесь: https://stackoverflow.com/a/12342937/4747587

person Henry    schedule 07.11.2015
comment
Я не думаю, что это решает проблему. У меня один и тот же отчет о сбое появляется несколько раз, но в моем коде нет asyncTasks. Я установил адаптер и onItemClickListener в onCreateView фрагмента. Вопрос в том, как можно щелкнуть элемент в списке фрагмента, который уже сохранил свое состояние. Этот отчет о сбое не имеет никакого смысла. - person Jonas; 04.12.2015