Xamarin Android:Firebase前台通知接收后页面图标不显示问题求助
问题描述
开发Xamarin跨平台应用的Android端,使用FirebasePushNotification Plugin v3.4.35。已按插件要求创建MainApplication类处理通知回调,在OnCreate方法中注册了CrossFirebasePushNotification.Current.OnNotificationReceived事件处理程序,应用处于前台时该事件可正常触发并捕获通知。
主页面OverViewPage中有一个ImageButton,其IsVisible属性绑定到所有ViewModel继承的BaseViewModel中的HaveNotification布尔属性。当OnNotificationReceived事件触发时,实例化新的BaseViewModel并设置HaveNotification=true,但页面图标未响应属性变化显示。询问是否是设置属性的位置导致问题,以及如何让图标在事件触发时显示。
相关代码
MainApplication类
public class MainApplication : Application { public MainApplication(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer) { } public override void OnCreate() { base.OnCreate(); //... 移除无关代码 CrossFirebasePushNotification.Current.OnNotificationReceived += (s, p) => { System.Diagnostics.Debug.WriteLine("Received"); BaseViewModel baseviewmodel = new BaseViewModel { HaveNotification = true }; }; } }
BaseViewModel类
public class BaseViewModel : INotifyPropertyChanged { bool haveNotification = false; public bool HaveNotification { get { return haveNotification; } set { SetProperty(ref haveNotification, value); } } protected bool SetProperty<T>(ref T backingStore, T value, [CallerMemberName] string propertyName = "", Action onChanged = null) { if (EqualityComparer<T>.Default.Equals(backingStore, value)) return false; backingStore = value; onChanged?.Invoke(); OnPropertyChanged(propertyName); return true; } #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = "") { var changed = PropertyChanged; if (changed == null) return; changed.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #endregion }
OverViewPage布局
<StackLayout Orientation="Horizontal" Margin="0,0,0,0" WidthRequest="250" BackgroundColor="{StaticResource Primary }"> <ImageButton x:Name="ibtnNotify" IsVisible="{Binding HaveNotification}" Source="@drawable/icon_msg.png" BackgroundColor="Yellow" HorizontalOptions="End"/> </StackLayout>
问题分析与解决方案
问题根源
- ViewModel实例不匹配:你在通知回调中新建的
BaseViewModel是一个独立实例,和OverViewPage绑定的ViewModel不是同一个对象。修改新实例的属性不会触发页面绑定的更新,因为页面监听的是自身绑定的ViewModel的PropertyChanged事件。 - 线程问题:Firebase的通知回调可能运行在非UI线程,直接修改绑定属性可能导致UI更新失败或异常。
解决方法
方法1:修改页面绑定的实际ViewModel实例
直接找到OverViewPage当前绑定的ViewModel并更新属性,记得切换到主线程操作:
CrossFirebasePushNotification.Current.OnNotificationReceived += (s, p) => { System.Diagnostics.Debug.WriteLine("Received"); // 切换到UI线程执行属性更新 Device.BeginInvokeOnMainThread(() => { if (Application.Current.MainPage is OverViewPage mainPage) { if (mainPage.BindingContext is BaseViewModel vm) { vm.HaveNotification = true; } } }); };
方法2:使用全局状态管理(更推荐)
创建全局单例的通知状态类,避免页面耦合,同时支持多页面共享状态:
- 定义全局状态类
public class NotificationState : INotifyPropertyChanged { private static NotificationState _instance; public static NotificationState Instance => _instance ??= new NotificationState(); private bool _haveNotification; public bool HaveNotification { get => _haveNotification; set { if (_haveNotification != value) { _haveNotification = value; OnPropertyChanged(); } } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
- 修改页面绑定到全局单例
<ImageButton IsVisible="{Binding Source={x:Static local:NotificationState.Instance}, Path=HaveNotification}" Source="@drawable/icon_msg.png" BackgroundColor="Yellow" HorizontalOptions="End"/>
- 在通知回调中更新全局状态
CrossFirebasePushNotification.Current.OnNotificationReceived += (s, p) => { System.Diagnostics.Debug.WriteLine("Received"); Device.BeginInvokeOnMainThread(() => { NotificationState.Instance.HaveNotification = true; }); };
核心注意点
无论用哪种方法,必须通过Device.BeginInvokeOnMainThread将属性更新操作切换到UI线程,否则可能导致UI不更新或抛出线程异常。
内容的提问来源于stack exchange,提问作者Gary H
相关产品推荐
相关产品推荐

