Xamarin中MainActivity被销毁后如何创建通知并解决异常?
问题分析与解决方案
问题概述
应用基于周期性后台任务,活跃状态运行正常,但数小时后系统会杀死MainActivity(已获取电池不优化权限),后台服务仍持续运行。此时后台服务显示通知时抛出异常:You must call Xamarin.Forms.Forms.Init(); prior to using this property.,且无法启动依赖通知的前台服务。尝试通过广播显示通知时,manager.Notify(messageId++, notification);处出现NullReference异常。
核心问题定位
- Xamarin.Forms初始化异常:后台服务调用通知时,因MainActivity被销毁,Xamarin.Forms上下文未初始化,导致依赖Forms的代码报错。
- NullReference异常(广播方案):BroadcastReceiver中的
manager变量未初始化,直接调用Notify触发空引用。
具体修复步骤
1. 修复广播接收器的空引用问题
在BroadcastReceiver的OnReceive方法中,先初始化NotificationManager:
public override void OnReceive(Context context, Intent intent) { // 初始化NotificationManager manager = (NotificationManager)context.GetSystemService(Context.NotificationService); PendingIntent pendingIntent = PendingIntent.GetActivity(AndroidApp.Context, pendingIntentId, intent, PendingIntentFlags.OneShot | PendingIntentFlags.Immutable); string title = intent.GetStringExtra(AndroidNotificationManager.TitleKey); string message = intent.GetStringExtra(AndroidNotificationManager.MessageKey); NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId) .SetContentIntent(pendingIntent) .SetContentTitle(title) .SetContentText(message) .SetLargeIcon(BitmapFactory.DecodeResource(context.Resources, Resource.Drawable.Logo2_6_10x10)) .SetSmallIcon(Resource.Drawable.Logo2_6_10x10) .SetStyle(new NotificationCompat.BigTextStyle().BigText(message)); Notification notification = builder.Build(); notification.Flags = NotificationFlags.AutoCancel; manager.Notify(messageId++, notification); }
2. 脱离Xamarin.Forms上下文显示通知
后台服务中直接使用Android原生API创建通知,依赖Application上下文而非MainActivity,避免Forms初始化限制:
public void Show(string title, string message, int Id, string Type) { try { var appContext = global::Android.App.Application.Context; // Android 8.0+必须先创建通知渠道 CreateNotificationChannel(appContext); Intent intent = new Intent(appContext, typeof(MainActivity)); intent.AddFlags(ActivityFlags.SingleTop); intent.PutExtra(TitleKey, title); intent.PutExtra(MessageKey, message); intent.PutExtra(MsgIdKey, Id.ToString()); intent.PutExtra(MsgTypeKey, Type); var pendingFlags = PendingIntentFlags.UpdateCurrent; if ((int)Build.VERSION.SdkInt >= 33) pendingFlags |= PendingIntentFlags.Immutable; PendingIntent pendingIntent = PendingIntent.GetActivity(appContext, pendingIntentId++, intent, pendingFlags); NotificationCompat.Builder builder = new NotificationCompat.Builder(appContext, channelId) .SetContentIntent(pendingIntent) .SetContentTitle(title) .SetContentText(message) .SetLargeIcon(BitmapFactory.DecodeResource(appContext.Resources, Resource.Drawable.Logo2_6_10x10)) .SetSmallIcon(Resource.Drawable.Logo2_6_10x10) .SetStyle(new NotificationCompat.BigTextStyle().BigText(message)); Notification notification = builder.Build(); notification.Flags = NotificationFlags.AutoCancel; var notificationManager = (NotificationManager)appContext.GetSystemService(Context.NotificationService); notificationManager.Notify(messageId++, notification); } catch(Exception ex) { Console.WriteLine($"通知显示失败:{ex.Message}"); } } // 创建通知渠道的辅助方法 private void CreateNotificationChannel(Context context) { if ((int)Build.VERSION.SdkInt >= 26) { var channel = new NotificationChannel(channelId, "默认通知渠道", NotificationImportance.Default) { Description = "应用通知渠道" }; var notificationManager = (NotificationManager)context.GetSystemService(Context.NotificationService); notificationManager.CreateNotificationChannel(channel); } }
3. 优化后台服务存活能力
将后台服务设为前台服务,启动时立即显示前台通知,降低被系统杀死的概率:
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId) { // 创建前台通知 var foregroundNotification = new NotificationCompat.Builder(this, channelId) .SetContentTitle("后台服务运行中") .SetContentText("应用正在后台执行周期性任务") .SetSmallIcon(Resource.Drawable.Logo2_6_10x10) .Build(); // 启动前台服务 StartForeground(1, foregroundNotification); // 执行周期性任务逻辑 return StartCommandResult.Sticky; }
注意:Android 12+需在
AndroidManifest.xml中添加<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />权限。
4. 简化方案(可选)
如果直接通过后台服务原生API显示通知能解决问题,可移除广播中转逻辑,减少代码复杂度。
内容的提问来源于stack exchange,提问作者DCV
相关产品推荐
相关产品推荐

