我有一个Xamarin Forms
应用程序,我使用MessagingCenter
将某些数据从特定平台发送到Xamarin.Forms
应用程序。
在我的Page
我订阅base.OnAppearing()
中的邮件并取消订阅base.OnDisappearing()
方法。这可以按预期工作。
我遇到的问题是,当AndroidOS
停止应用程序时(例如,当我更改设备的语言时),我开始获取消息的副本。我很困惑为什么会这样,但我注意到重启应用程序时没有调用base.OnDisappearing()
方法。
有谁知道什么可能导致我的问题以及如何解决它?
另外,Xamarin
中是否有任何方式可以查看您的所有发布商和订阅者?
答案 0 :(得分:3)
像Greensy所说,除了订阅 Warning: unlink() expects parameter 1 to be a valid path, array given in /var/www/html/web/copy.php on line 13
Files were successfully deleted
和取消订阅OnAppearing()
之外,我还在订阅前取消订阅消息,因为,为什么不:
OnDisappearing()
答案 1 :(得分:1)
在Xamarin.Forms v2.3.4.247中,在Android上,在测试中,我们发现当一个模态页面位于导航页面顶部并且你离开应用程序时,导航页面调用了它的OnDisappearing()方法而不是实际在顶部的模态页面。 为了解决这个问题,我们做了以下工作: - 在OnAppearing方法中,检查您是否真的在顶部 - 如果你在顶部,一切都很好 - 如果您不在顶部,请自行调用SendDisappearing(),并在实际页面上调用SendAppearing()。我们还发现您需要在页面顶部调用SendDisappearing(),因为Xamarin表单可以保护这些方法免受多次调用。换句话说,如果你两次调用SendDisappearing(),它只会执行一次。
这是一个适合我们的例子,因为我们有一个BaseContentPage,所有页面都来自这个页面:
protected override void OnAppearing()
{
base.OnAppearing();
var pageOnTop = ModalContentPageOnTop();
if (pageOnTop == null || pageOnTop == this)
{
// do some stuff, like setting up subscriptions
SetupSubscriptions();
}
else
{
// Xamarin Forms Appearing/Disappearing Bug
// Found that when you leave the Android app with a modal page on top of a non-modal page (either minimise the app or lock the device), then Xamarin.Forms does not properly call OnAppearing.
// Xamarin.Forms will call OnAppearing on the non-modal page and not on the modal page. This would not only cause message subscriptions to not be set up on the modal page,
// but would also set up message subscriptions on the non-modal page. Not good. Hopefully, this work-around should stop being executed when Xamarin fixes the problem, as we won't
// fall into this "else" condition above, because OnAppearing will be called on the right page.
// NOTE: SendDisappearing and SendAppearing have boolean guards on them. If SendAppearing was called last, calling it again will do nothing.
// SendDisappearing has the same behaviour. Thus we need to call SendDisappearing first, to be guaranteed that SendAppearing will cause the OnAppearing() method to execute.
((IPageController)pageOnTop).SendDisappearing(); // try and correct Xamarin.Forms - the page actually on top was not told it was disappearing - tell it now
((IPageController)this).SendDisappearing(); // try and correct Xamarin.Forms - if it thinks the view has appeared when it hasn't, it won't call OnAppearing when it is truly appearing.
((IPageController)pageOnTop).SendAppearing(); // try and correct Xamarin.Forms by notifying the correct page that it is appearing
}
}
ModalContentPageOnTop的样子:
private ContentPage ModalContentPageOnTop()
{
var page = Navigation.ModalStack.LastOrDefault();
var navigationPage = page as NavigationPage;
if (navigationPage != null)
return navigationPage.CurrentPage as ContentPage;
return page as ContentPage;
}
我们的应用程序中有一个非常浅的导航层次结构,因此这种方法可能无法用于更复杂的导航堆栈(即推送其他页面或其他模态页面的模态页面)
答案 2 :(得分:0)
我通过做这样的事情解决了我的问题 -
MessagingCenter.Subscribe<string, DetailClass>(this, "KeyHere", async (detail) =>
{
// do someting....
MessagingCenter.Unsubscribe<string,DetailClass>(this, "KeyHere");
});
以订阅方式取消订阅邮件中心。
答案 3 :(得分:0)
您可以在页面构造函数中OnAppearing
之后订阅它,而不是使用OnDisappearing
和InitializeComponent()
,而是取消订阅:
protected override void OnParentSet()
{
base.OnParentSet();
if (Parent == null)
{
// unsubscribe
}
}
OnParentSet
在OnAppearing
之前和OnDisappearing
之后被调用。但是,在从导航堆栈中删除页面或弹出页面时,Parent仅在页面上变为空。这可以确保它们只被调用一次,而我注意到OnAppearing
并且OnDisappearing
并不总是被一致地调用,具体取决于弹出窗口和/或其他内容的显示方式。
答案 4 :(得分:0)
该问题原来与Xamarin.Forms没有直接关系,但是是由于在我的BroadcastReceiever
类内的OnStop
方法中未正确注销MainActivity
的问题所致。因此,每当应用程序经历OnStop/OnStart
周期时,即使我只有一个活动订阅,也会发送2条消息。
我还在Xamarin.Forms ContentPages上的Unsubsribe
方法中调用OnDisappearing
,并且在Unsubscribe
方法中调用Subscribe
之前也调用了OnAppearing
。
到目前为止,我在任何设备或不同的Android版本上都没有再遇到此问题。
还有一些其他建议,请不要忘记取消订阅OnDisappearing方法中剩余的所有MessagingCenter订阅,否则您将遇到一些奇怪的错误,这会使您的头发变白。关于该主题有一篇不错的文章,但我找不到它。