Xamarin Forms .NET Standard 2.0本地通知遇Java类未找到异常求助
这个Java.Lang.ClassNotFoundException错误在Xamarin Android场景里很常见,核心原因通常是链接器移除了未被直接引用的绑定类,或者自定义广播接收器(也就是这里的ScheduledAlarmHandler)没有正确注册。下面先给你解决当前问题的步骤,再推荐更省心的本地通知实现方案。
一、修复当前的ClassNotFoundException问题
确保广播接收器正确注册
如果ScheduledAlarmHandler是你自定义的广播接收器类,需要在Android项目中给它加上[BroadcastReceiver]特性,同时确保它继承自BroadcastReceiver:[BroadcastReceiver(Enabled = true)] [Android.Runtime.Preserve(AllMembers = true)] public class ScheduledAlarmHandler : BroadcastReceiver { // 你的接收器逻辑 public override void OnReceive(Context context, Intent intent) { // 处理通知触发逻辑 } }或者手动在
AndroidManifest.xml里注册:<receiver android:name="md54b33d38a21a950def308c8bb6f6e0d30.ScheduledAlarmHandler" android:enabled="true" />注意:那个md5前缀是Xamarin自动生成的类名,如果你重命名了类或修改了命名空间,这个值可能会变化,用特性自动注册会更稳妥。
阻止链接器移除该类
Xamarin Android的链接器会在发布模式下移除未被直接引用的代码,导致这个类被误删。可以通过两种方式解决:- 在类上添加
[Android.Runtime.Preserve(AllMembers = true)]特性(上面的代码已经包含),告诉链接器保留这个类的所有成员。 - 在Android项目的属性 -> Android Options -> Linker中,选择"Link SDK assemblies only",或者把包含该类的程序集设置为"Do not link"。
- 在类上添加
清理重建解决方案
有时候是缓存导致的问题,手动删除所有项目的bin和obj文件夹,然后重新编译整个解决方案。
二、更优的本地通知实现方案
如果你不想再处理这类绑定类的麻烦,推荐使用Plugin.LocalNotification这个专门为Xamarin Forms打造的本地通知库,它封装了iOS和Android的原生通知API,配置简单,不需要自己写广播接收器或处理复杂的原生逻辑。
步骤如下:
安装NuGet包
在你的.NET Standard共享项目、Android项目和iOS项目中,都安装Plugin.LocalNotificationNuGet包。平台配置
Android:在
MainActivity.cs的OnCreate方法中初始化通知通道:protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // 初始化通知通道(Android 8.0及以上必需) LocalNotificationCenter.CreateNotificationChannel(); Xamarin.Essentials.Platform.Init(this, savedInstanceState); global::Xamarin.Forms.Forms.Init(this, savedInstanceState); LoadApplication(new App()); }同时在
AndroidManifest.xml中添加Android 13及以上所需的通知权限:<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />iOS:在
AppDelegate.cs的FinishedLaunching方法中初始化:public override bool FinishedLaunching(UIApplication app, NSDictionary options) { LocalNotificationCenter.Initialize(); global::Xamarin.Forms.Forms.Init(); LoadApplication(new App()); return base.FinishedLaunching(app, options); }还要在
Info.plist中添加通知权限描述(iOS 10及以上必需):<key>NSUserNotificationUsageDescription</key> <string>需要发送本地通知提醒您</string> <key>NSRemoteNotificationUsageDescription</key> <string>需要发送本地通知提醒您</string>
发送本地通知的示例代码
在共享项目中直接调用即可,无需区分平台:using Plugin.LocalNotification; // 发送即时通知 var notification = new NotificationRequest { NotificationId = 1001, Title = "新消息提醒", Description = "您有一条未读消息", BadgeNumber = 1 // iOS上的角标数 }; await LocalNotificationCenter.Current.ShowNotification(notification); // 发送定时通知 var scheduledNotification = new NotificationRequest { NotificationId = 1002, Title = "定时提醒", Description = "10分钟后要开会啦", Schedule = new NotificationRequestSchedule { NotifyTime = DateTime.Now.AddMinutes(10) } }; await LocalNotificationCenter.Current.ShowNotification(scheduledNotification);
这个库还支持自定义通知样式、点击通知跳转页面等功能,比自己手动实现原生通知要省心很多,也能避免类似的类找不到的问题。
内容的提问来源于stack exchange,提问作者Leaf Leafword

