Я использую библиотеку поддержки v4 в нашем приложении, и у меня есть пошаговый процесс в приложении, который нормально работает в обычных условиях. Однако у нас есть требование, чтобы все работало и не вылетало из-за нехватки памяти. Поэтому я использую библиотеку SetAlwaysFinish, чтобы помочь с этим (https://github.com/bricolsoftconsulting/SetAlwaysFinish а>). Это было чрезвычайно полезно для определения областей, в которых необходимо обнаруживать и обрабатывать подобные ситуации, но я столкнулся с одной, которая поставила меня в тупик. Имейте в виду, что это нормально работает при нормальных обстоятельствах, но я явно тестирую с «setAlwaysFinish» = ON.
Вот моя установка: у меня есть класс ProcessActivity, в котором размещается макет для ViewPager. У ViewPager есть набор адаптеров, который содержит мой список фрагментов, которые будут охватывать процесс. Это в методе onCreate():
ProcessActivity:
createSteps(); // this creates/populates the ArrayList "processSteps" with Fragments
theAdapter = new ProcessAdapter(this, processSteps); // the ProcessAdapter class extends FragmentStatePagerAdapter, with an additional list of Fragment steps
theViewPager.setAdapter(theAdapter);
Есть и другие части, но это ядро того, как это настроено. Во время одного из шагов фрагмента мне действительно нужно «вырваться» из процесса шага и временно перейти к действию, чтобы выполнить некоторую логику (а затем вернуться к процессу шага). Я делаю это следующим образом с ForResult, так как мне нужно иметь возможность обрабатывать действие OK/Cancel в действии, когда оно завершается:
Фрагмент Step4:
Intent intent = new Intent(getActivity(), ThePushActivity.class);
intent.putExtra(blah..);
startActivityForResult(intent, THE_REQCODE);
После того, как он попал в это представление, иногда вызывается метод onDestroy() как ProcessActivity, так и Step4Fragment (из-за alwaysFinish). Иногда кажется, что он работает нормально и вызывает обратно процесс Step-Fragment. Но обычно он вызывает метод onDestroy() ProcessActivity, а затем повторно вызывает метод onCreate() с заполненным состоянием сохраненного экземпляра пакета. Это вызовет приведенный выше код создания шага и поместит приложение в странное состояние, где отображается последний шаг, на котором был пользователь, но за кулисами он на самом деле находится на первом шаге (фрагменты в этот момент находятся за пределами). удар и разъединение), и неизбежно происходит сбой. На данный момент кажется, что Step4Fragment полностью разъединен и где-то рухнет, если вы попытаетесь что-то сделать, даже если кажется, что он был правильно воссоздан.
Любые мысли о лучших способах решения этой проблемы? Я думаю, что это нормально, если я найду способ даже просто сбросить настройки, чтобы пользователь возвращался к первому шагу процесса, если возникает проблема с памятью. Впрочем, вся моя забота — это, конечно, крушение.
Дайте мне знать, если мне нужно предоставить более подробную информацию. Заранее благодарю за любую помощь!
ОБНОВЛЕНИЕ № 1: Просто быстрое обновление, которое я заметил, что фрагменты повторно создаются и инициализируются, и они правильно попадают в метод onActivityResult() «текущего» фрагмента и делают то, что ему нужно. делать правильно. Кажется, что разъединение лежит в базовом классе ProcessActivity, следуя одному из этих сценариев. Макет ViewPager отображается правильно, но все, что находится за пределами ViewPager, неверно (т.е. он указывает, что он находится на 1-м этапе процесса, когда он должен указывать, что он находится на 4-м, и кнопки навигации отображаются для 1-го шага а не 4-й).
Поэтому я предполагаю, что мне нужно как-то правильно установить эти элементы вручную. Углубляясь в это, я могу упустить фрагменты кода, которые необходимы кому-то, чтобы активно помочь с этим. Если бы я мог каким-то образом получить доступ к состоянию поля ViewPager, которое содержит возможность получить «текущий показанный фрагмент», до того, как был вызван весь этот onDestroy()/onCreate(), возможно, из пакета saveInstanceState? Это, вероятно, решило бы мою проблему. Но при проверке этого пакета при отладке я вижу только сами фрагменты и их соответствующие состояния. Однако я продолжу копать.
В любом случае, пожалуйста, дайте мне знать, если у кого-нибудь есть какие-либо идеи о том, как правильно это сделать (на высоком уровне, конечно).
ОБНОВЛЕНИЕ № 2 Я вижу, что даже если "текущий" фрагмент кажется инициированным правильно, и представление отображается правильно, все отсоединено. Я не могу вызывать какие-либо методы для getResources() или getActivity() и т. д. На самом деле мне удалось заставить ProcessActivity «работать» правильно, основываясь на сохранении индекса шага (int) в пакете saveInstanceState, а затем перезагрузке пользовательского интерфейса. элементы вокруг него. Тем не менее, у меня все еще есть этот блокировщик с текущим фрагментом, отсоединенным от действия, хотя он, по-видимому, повторно создается правильно.
ОБНОВЛЕНИЕ №3 Когда я следую указаниям этого поста: ViewPager и фрагменты — как правильно хранить состояние фрагмента?, я получаю немедленное исключение, когда пытаюсь выполнить первый putFragment(). Исключением является: «IllegalStateException: Fragment Step4Fragment в настоящее время отсутствует в FragmentManager». Я думаю, это может быть связано с тем фактом, что я держу только один фрагмент слева и один фрагмент справа «активным» в любой момент времени (т.е. offScreenPageLimit).