Представление фрагмента застревает на экране, даже когда работает другой фрагмент - PullRequest
0 голосов
/ 03 июня 2019

«Старая» версия фрагмента (содержащая старые данные) «застряла» на дисплее: простой текст (подтверждающий регистрацию, меняется) не изменяется в TextView, установленном в onResume. Фрагменты (которые должны заменять этот фрагмент) работают корректно (но невидимо) - экран виден непрозрачно, но «прозрачен» на ощупь - и регистрация показывает, что фрагменты правильно меняются местами.

  • Только на Android P (отлично работает на O)
  • Только тогда, когда приложение уже перешло в спящий режим (до тех пор работает нормально). Иногда требуется два сна после перезапуска приложения.
  • Фрагменты ведут себя правильно «снизу» (клики ведут себя правильно, логи выглядят правильно, побочные эффекты корректны)
  • Более радикальные действия (переход к обзору и возврат из него, вращение) дают правильное отображение (временно).

Проверено на реальном оборудовании и эмуляторе на Oreo, эмулятор только на Pie.

(Извинения: я даже не уверен, какие конкретные вопросы задавать или какой код был бы уместен, пожалуйста, предложите, что может помочь. Пожалуйста, имейте в виду ограничения выше только для P и только после сна.)

Подробности: Это приложение занимает весь экран, что подходит для целевой аудитории (не для вашего обычного пользователя телефона). Специализированный аудиоплеер. Работает по API 17-28 (с "древним" оборудованием конкретной цели).

Здесь все в одном действии, включающем два фрагмента. Один - это очень простой фрагмент с несколькими кнопками (указывающими на воспроизведение звука), другой - ViewPager с довольно простыми представлениями. Я полагаю, что оба фрагмента имеют проблему, какой бы она ни была, но мы сконцентрируемся на простом «игровом» фрагменте.

Приложение запускается во фрагменте ViewPager, в котором есть кнопка для перехода к «воспроизводимому» фрагменту (который запускает звук). Этот фрагмент по сути является полноэкранной кнопкой STOP, на которой отображается немного другой информации и пара других кнопок, которые здесь не используются. Нажатие на клавишу «Стоп» возвращает к пейджеру просмотра и работает правильно большую часть времени.

Однако при запуске на эмуляторе Android для Pie, если экрану разрешено время ожидания в состоянии «воспроизведения», а затем перезапущен с помощью кнопок «назад» или «питание» на панели инструментов эмулятора, кнопка остановки фрагмента работает (кнопка вызывается обработчик кнопки), фрагменты изменяются (в соответствии с распечатками журнала), но фактическое отображение на экране не изменяется. (Иногда для этого требуется два сна, НИКОГДА не более двух.) В этом случае кнопки для экрана ViewPager активны, и регистрация показывает, что они вызываются, если я нажимаю на них вслепую. Если я нажму (невидимую) кнопку запуска, фрагменты (согласно журналу) снова изменятся, и звук перезапустится. Это может продолжаться вечно. (Значок «Воспроизведение звука» в строке состояния системы появляется и уходит, когда это необходимо.) Если нажать кнопку «Обзор» и затем нажать на приложение, произойдет правильное обновление экрана до соответствующего экрана. Поворот (но только после нажатия новой кнопки «Повернуть меня») также исправляет это.

Я поместил статический счетчик int в «воспроизводимый» фрагмент и вижу, что он увеличивается на onCreateView, как и ожидалось (видно из журналов). Он также отображается на экране в onResume в TextView, и это НЕ меняется при попадании в ошибку. Журналы подтверждают, что вызывается onResume. На экране мигает текст, но он не мигает, когда это происходит (до полного обновления с использованием «обзора» или поворота).

Я также записываю местоположение объекта для «играющего» фрагмента, и оно не меняется. Сообщения журнала подтверждают, что память для класса не используется повторно. (Я использую нестатический счетчик для подсчета вызовов onCreateView, и он растет, а не сбрасывается до нуля, как это было бы, когда класс воссоздается полностью.) Журналы подтверждают полный жизненный цикл от onCreateView до onDestroyView, в то время как отображение остается без изменений.

Я использую androidx / SupportFragmentManager.

Я пробовал большое количество «случайных» вещей:

  • использование явных циклов отсоединения / присоединения в менеджере фрагментов
  • установка видимости GONE в onPause, восстановление его в onResume (он остается GONE, поврежденное изображение теперь пустое, что согласуется с игнорированием onResume!) (Выполнение обоих в onPause не работает).
  • вызов ViewGroup # invalidate () (без видимого эффекта) (пробуется как на фрагментном кадре, так и на полном экране).
  • выталкивание backstack перед переключением фрагментов (без эффекта, 0 backstack)
  • довольно много предложений StackOverflow
  • использование postDelayed () для дополнительных вызовов onResume (они регистрируются, но без видимого эффекта). (Отчаяние!)
  • отключение кода, который я считаю потенциально нечетным.

Иногда они немного меняют ситуацию, но ни одна из них не устранила основную проблему. Кто-нибудь может предложить лучшие вопросы / эксперименты? Принимая во внимание количество (запутанного) кода, стрельба из этого кода только ухудшит ситуацию. Все это на github, если вы хотите посмотреть на него. (https://github.com/DonnKey/homerplayer.) Ошибка повторяется в последней версии, прежде чем я вмешался, если это какая-то подсказка.

Опять же, извините за расплывчатый вопрос, но я застрял даже за способы напасть на это.

...