Я сталкиваюсь с сбоем, когда, если операционная система Android убивает процесс, когда приложение пытается восстановить действие и фрагмент из сохраненного экземпляра, адаптер моего recyclerview всегда имеет значение null.
Вот мойиерархия:
Parent Activity // destroyed when process is killed
Nested View Pager Fragment // view pager containing four recycler view fragments
Recycler Frag 1
Recycler Frag 2
Recycler Frag 3
Recycler Frag 4
Каждый из этих фрагментов утилизатора является точно таким же фрагментом, за исключением того, что когда родительское действие создает их новый экземпляр, я вызываю открытый метод сеттера, который устанавливает адаптер типа RecyclerView.Adapter.(причина в том, что каждый из этих фрагов может быть переработчиком страниц, но его содержимое и способы взаимодействия с ним могут отличаться) Пример кода из родительского действия:
RecyclerFrag feedFrag = RecyclerFrag.newInstance();
feedFrag.setAdapter(new myCustomAdapter());
Теперь, мои конечные пользователиприводят к аварийному завершению работы, когда, если они имеют фоновое действие этого действия, и ОС решает прекратить процесс, на котором оно действует, оно не восстанавливается должным образом.Из того, что я вижу, все на восстановлении кроме адаптера, который является нулевым.Затем код пытается получить доступ к интерфейсу адаптеров и падает с помощью NPE.
Я не могу понять, почему это происходит.Я также пытаюсь обернуть голову вокруг восстановления действий и фрагментов в подобных событиях.Я прочитал кучу постов и документации о восстановлении состояния и до сих пор не могу найти решение.Вот пример решений, которые я попробовал, и, возможно, кто-то может указать на изъян / пробел в моей логике.
Пусть утилита frag хранит себя в fragManager и пытается прочитать его обратно при вызове метода onActivityCreated.
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
getFragmentManager().putFragment(outState, "myFrag", this);
...
}
затем:
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(savedInstanceState != null) {
getFragmentManager().getFragment(savedInstanceState, "myFrag");
...
}
}
Мне кажется, что мне не хватает знака.Для фрагмента не имеет смысла захватывать ссылку на себя, а затем пытаться установить себя из него.Хуже того, возвращаемый фрагмент имеет нулевой адаптер.Живи и учись.
Далее я попытался сохранить фрагменты, созданные в родительском действии, для реализации viewPager, а затем попытаться восстановить эти фрагменты в родительском onCreate.Родительский класс будет выглядеть следующим образом:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "frag1", frag1);
...
}
затем:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null) {
getSupportFragmentManager.getFragment(savedInstanceState, "myFrag);
...
}
}
Интересно отметить, что при таком подходе я сохраняю фрагмент в диспетчере в onSaveInstance
Метод, мой adpater не является нулевым, что имеет смысл.Когда я получаю его в методе onCreate, этот адаптер фрагментов теперь имеет значение null.
В связи с этим у меня остается заключительная мысль, что, возможно, восстановление адаптера неэффективно и не должно выполняться таким образом.Еще раз, для меня нет смысла создавать адаптер внутри фрагмента Recycler, так как я хочу, чтобы этот фрагмент принимал любую реализацию адаптера типа RecyclerView.Adapter
.Для дальнейшего контекста реализация viewPager имеет тип FragmentStatePagerAdapter
, который предоставляет метод минимума, переопределяющий его запуск.Насколько я понимаю, это именно то, что вы должны сделать, и родитель FragmentStatePagerAdapter
будет выполнять остальную часть процесса восстановления для вас.Я ошибаюсь в этом предположении?
Буду очень признателен за любой вклад в этот вопрос.Однако я постарался предоставить как можно больше информации, если вы считаете, что можете помочь мне, предоставив больше информации, я был бы рад обновить мой пост, если вы просто дадите мне знать.Спасибо!
Окончательное редактирование: В итоге я выбрал решение, аналогичное тому, которое помечено как ответ на этот пост.Ниже я приведу свое реальное решение, поэтому, если кто-то в будущем сочтет этот пост полезным для своей ситуации.
- Удалите метод открытого сеттера в интерфейсе фрагментов рециркуляции.Учитывая, что я всегда вызывал сеттер сразу после инициализации фрагмента, было понятно, что с этим подходом что-то не так, и он подвержен ошибкам, когда будущим разработчикам приходится работать с кодом.
- Создайте перечислимый тип в качестве абстракции данных для объектов в утилизаторе.Учитывая, что для определенных подразумеваемых типов данных требовались разные адаптеры, это также представляется целесообразным.Под этим я подразумеваю, что у меня может быть автомобильный объект, но в зависимости от того, где я нахожусь в путешествии пользователя, этому автомобильному объекту может потребоваться другой адаптер, отображаемый с помощью перечислений, таких как
CAR_PREVIEW_SEARCH
или CAR_PREVIEW_SELECTABLE
, который входит в игру во время * 1046.*