В 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 на физическом устройстве.
Я также пробовал разные комбинации линкеров. Нет эффекта.
Ответы
Ответ 1
Для IOS 8 используйте Alert Controllers.
https://developer.xamarin.com/recipes/ios/standard_controls/alertcontroller/
var okAlertController = UIAlertController.Create ("OK Alert", "This is a
sample alert with an OK button.", UIAlertControllerStyle.Alert);
Ответ 2
Попробуйте:
Device.BeginInvokeOnMainThread(ShowAlertAndWaitForUser(currentFabricCount).Result);
Ваша проблема очень распространена в ситуациях, когда код не запускается в потоке Main/UI. Кажется, что вы начинаете вызов в главном потоке, но поток пользовательского интерфейса фактически не читает строку, а другой поток выполняет необходимые действия. И это также, почему это работает несколько раз и не работает в другое время.
Таким образом, вместо выполнения всего ShowAlertAndWaitForUser()
в потоке пользовательского интерфейса, попробуйте вместо этого запустить только функцию ShowAlert в этом потоке.
Ответ 3
У меня была похожая проблема с плагином Acr.UserDialogs
при отображении экрана загрузки на Android.
кажется, ваш основной поток используется, вместо Device.BeginInvokeOnMainThread
просто вызовите код с помощью await ShowAlertAndWaitForUser(currentFabricCount)
, сделав DoSomethingForNow
методом async
.
И его хорошая идея - реализовать INotifyPropertyChanged в классе viewmodel, а затем связать его, а скорее сбросить все в коде.