ProgressBar не сбрасывает к “0” при открытии во второй раз

В приложении Android я выполняю задачу в отдельном потоке. В то время как поток работает, он обновляет индикатор выполнения в главном окне для уведомления пользователя, что продолжается. Проблема, что, если пользователь запускает поток во второй раз, индикатор выполнения не будет сброшен. Это будет просто находиться на 100%, ничего не делая.

Целый источник доступен на GitHub. Как пример берут BackupThread и JsonBackup (основной класс). Обратите внимание, что "RestoreThread" показывает то же поведение, но я предполагаю, что в обоих случаях проблема идентична.

На быстром обходе через:

Приблизительно в строке 300 в JsonBackup.java, я открываю новый ProgressDialog. Поскольку это - новый экземпляр, я предполагаю, что все инициализируется правильно. На моей текущей рабочей копии я добавил строку, устанавливающую продвижение к "0", но это ничего не изменило. В том же блоке я создаю резервный поток и выполняю его.

Следующий бит кода интереса является моментом, когда поток связывается, это - продвижение назад к главному приложению. Это происходит вокруг строки 185 из BackupThread.java.

Сообщение обрабатывается в строке 80 из JsonBackup.java, которые обновят индикатор выполнения.

До сих пор для разбора программы. Одной вещью, которая ударила меня при записи этого, является строка 87 из JsonBackup.java. Я думаю, что было бы лучше, если бы поток отправил другое сообщение, явно указав, что это сделано. Но я предполагаю, что это не настоящая проблема здесь. Я говорю это, потому что диалоговое окно прогресса правильно отклоняет себя, после того как оно достигает 100%.

Так, если эта целая вещь выполняется однажды, все работает как ожидалось. Теперь примите, что пользователь оставляет приложение, но ОС решает оставить загруженным в памяти. Позже пользователь возвращается и хочет создать новое резервное копирование. Затем приложение не будет работать, поскольку прогресс зависает в 100%. При уничтожении приложения таким образом, оно полностью разгрузилось, оно будет работать снова. Таким образом, я предполагаю, что некоторый экземпляр объекта находится все еще в памяти и имеет грязное состояние, когда повторно выполнено. Но ни за что в жизни, я не могу найти то, что продолжается. Как касательная я мог бы добавить: Кроме учебных руководств по Блокноту, это - мое первое приложение для Android и bla di blah blah...

Что я пропускаю здесь...?

5
задан exhuma 13 September 2016 в 13:51
поделиться

2 ответа

Окно Dialog кэшируется Activity, это ожидаемое поведение.
Варианты:

  1. переопределить onPrepareDialog(...), чтобы сбросить его состояние
  2. вызвать removeDialog(...) перед тем, как показать его снова
  3. управлять диалогом самостоятельно, вручную вызывая show(), dismiss()

Я обычно выбираю #1 для часто используемых Dialogов и #3 для редких.

4
ответ дан 14 December 2019 в 19:05
поделиться

Я обычно использую onCreateDialog () плюс onPrepareDialog () для управления диалогами.

Из руководства для разработчиков Android:

Лучший способ определить методы обратного вызова onCreateDialog (int) и onPrepareDialog (int, Dialog) - использовать оператор switch, который проверяет параметр id, переданный в метод. В каждом случае необходимо проверить уникальный идентификатор диалогового окна, а затем создать и определить соответствующий диалог.

Метод onCreateDialog () вызывается один раз, когда диалог создается впервые; помещает сюда код, который инициализирует ваши диалоги.

Метод onPrepareDialog () вызывается каждый раз, когда отображается диалоговое окно.

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

Когда диалоговое окно должно быть закрыто, вы можете:

Если вы используете onCreateDialog (int) управлять состоянием ваших диалогов (как обсуждалось в предыдущем раздел), то каждый раз, когда ваш диалог отклонен, состояние диалога объект сохраняется Activity. Если вы решаете, что больше не будете нужен этот предмет или это важно что состояние очищено, то вы должен вызвать removeDialog (int). Этот удалит все внутренние ссылки на объект и если диалог показывая, он отклонит его.

1
ответ дан 14 December 2019 в 19:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: