Подтвердить что ты не робот

В Xamarin.Forms Device.BeginInvokeOnMainThread() не отображает окно сообщения из обратного вызова уведомления * только * в конфигурации Release на физическом устройстве

Я переписываю свое существующее (быстрое) iOS-приложение для физиотерапии "На моих нервах" в Xamarin.Forms. Это приложение таймера, чтобы помочь людям с повреждением нервов (как я!) Делать упражнения по десенсибилизации. У вас есть эти "ткани" (например, перо), где у каждой ткани есть второй обратный отсчет "х". Когда таймер фабрики достигает 0, появляется окно с сообщением "время истекло". Пользователь нажимает OK, и следующая матрица начинает обратный отсчет. Промойте и повторите для всех тканей в списке. Вот видео, показывающее рабочий процесс. Поверьте мне на UX в видео.

Вот мой пример кода приложения, демонстрирующий такое поведение.

Метод DoSomethingForNow (простите за мою стратегию именования) - это обратный вызов из NotificationService (см. строку 65 - недостаточно точек повторения SO для прямой ссылки), который создается при запуске таймера на случай, если приложение получает фон.

Конкретный вызов, который не работает в режиме Release на устройстве, находится на линии 115

Device.BeginInvokeOnMainThread(
                async () => await ShowAlertAndWaitForUser(currentFabricCount));

async () => await ShowAlertAndWaitForUser(currentFabricCount)) работает должным образом в конфигурации Debug и Release на iOS Simulator и в конфигурации Debug на устройстве.

Однако окно сообщения, указывающее, что время истекло, не отображается в конфигурации выпуска на физическом устройстве. Я не могу понять, почему Device.BeginInvokeOnMainThread() не работает в Release config на устройстве. что происходит?

Примечание: используется Device.StartTimer()

Причина, по которой я перешел с Device.StartTimer() на решение James FrenchPressTimer (см. Jamesmontemagno/FrenchPressTimer) на раннем этапе, заключается в том, что мне нужен способ отменить/остановить/что угодно Device.StartTimer() на случай, если пользователю потребуется приостановить или остановить обратный отсчет времени на приложение.

Код Device.StartTimer() отлично работает для меня во всех конфигурациях как на симуляторе, так и на устройстве, и, к счастью, кто-то показал мне, как отменить Device.StartTimer (спасибо!). Если вы хотите увидеть это рабочее решение, проверьте saraford/Device-StartTimer-Working-Xamarin на GitHub.

Мой конкретный вопрос заключается в том, почему Device.BeginInvokeOnMainThread() не отображает окно сообщения при вызове из обратного вызова уведомления в Release config на физическом устройстве.

Я также пробовал разные комбинации линкеров. Нет эффекта.

4b9b3361

Ответ 2

Попробуйте:

Device.BeginInvokeOnMainThread(ShowAlertAndWaitForUser(currentFabricCount).Result);

Ваша проблема очень распространена в ситуациях, когда код не запускается в потоке Main/UI. Кажется, что вы начинаете вызов в главном потоке, но поток пользовательского интерфейса фактически не читает строку, а другой поток выполняет необходимые действия. И это также, почему это работает несколько раз и не работает в другое время.

Таким образом, вместо выполнения всего ShowAlertAndWaitForUser() в потоке пользовательского интерфейса, попробуйте вместо этого запустить только функцию ShowAlert в этом потоке.

Ответ 3

У меня была похожая проблема с плагином Acr.UserDialogs при отображении экрана загрузки на Android.

кажется, ваш основной поток используется, вместо Device.BeginInvokeOnMainThread просто вызовите код с помощью await ShowAlertAndWaitForUser(currentFabricCount), сделав DoSomethingForNow методом async.

И его хорошая идея - реализовать INotifyPropertyChanged в классе viewmodel, а затем связать его, а скорее сбросить все в коде.