Android端ScheduledAlarmHandler触发System.ArgumentNullException崩溃求助
Google Play应用后台触发本地通知时大量崩溃排查求助
应用在Google Play Store出现大量崩溃,无法定位来源及复现方式,推测崩溃发生在应用处于后台(或已被杀死)且触发本地通知时,堆栈追踪指向ScheduledAlarmHandler。
崩溃堆栈信息
Exception android.runtime.JavaProxyThrowable: System.ArgumentNullException: Value cannot be null. Parameter name: s at System.IO.StringReader..ctor (System.String s) [0x00009] in <2f4adfad501c4e4abfe6a9b300c1b849>:0 at (wrapper remoting-invoke-with-check) System.IO.StringReader..ctor(string) at LocalNotifications.Plugin.ScheduledAlarmHandler.serializeFromString (System.String notificationString) [0x00010] in <42e60f59bb2b4f93942a1c96f54643af>:0 at LocalNotifications.Plugin.ScheduledAlarmHandler.OnReceive (Android.Content.Context context, Android.Content.Intent intent) [0x0000c] in <42e60f59bb2b4f93942a1c96f54643af>:0 at Android.Content.BroadcastReceiver.n_OnReceive_Landroid_content_Context_Landroid_content_Intent_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_context, System.IntPtr native_intent) [0x00017] in <1eada6631e384353908e0dab9d072f35>:0 at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPLL_V (_JniMarshal_PPLL_V callback, System.IntPtr jnienv, System.IntPtr klazz, System.IntPtr p0, System.IntPtr p1) [0x00005] in <1eada6631e384353908e0dab9d072f35>:0 at crc6449389a0f4059adff.ScheduledAlarmHandler.n_onReceive at crc6449389a0f4059adff.ScheduledAlarmHandler.onReceive (ScheduledAlarmHandler.java:30) at android.app.ActivityThread.handleReceiver (ActivityThread.java:4497) at android.app.ActivityThread.access$1600 (ActivityThread.java:301) at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2188) at android.os.Handler.dispatchMessage (Handler.java:106) at android.os.Looper.loop (Looper.java:246) at android.app.ActivityThread.main (ActivityThread.java:8653) at java.lang.reflect.Method.invoke at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1130)
已尝试的方案
在OnReceive方法外层包裹PowerManager.WakeLock,但未解决崩溃问题。
相关代码
[BroadcastReceiver(Enabled = true, Exported = true)] [IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })] public class ScheduledAlarmHandler : BroadcastReceiver { public const string LocalNotificationKeyText = "LocalNotification_TEXT"; public const string LocalNotificationKeyID = "LocalNotification_ID"; public const string LocalNotificationKeyTitle = "LocalNotification_TITLE"; public NotificationManager manager; public override void OnReceive(Context context, Intent intent) { if (context != null) { PowerManager pm = (PowerManager)context.GetSystemService(Context.PowerService); PowerManager.WakeLock wakeLock = pm.NewWakeLock(WakeLockFlags.Partial, "ScheduledAlarmHandler"); wakeLock.Acquire(); var id = intent.GetIntExtra(LocalNotificationKeyID, 0); var title = intent.GetStringExtra(LocalNotificationKeyTitle); var text = intent.GetStringExtra(LocalNotificationKeyText); var notification = new LocalNotification(); notification.Title = title; notification.Text = text; notification.Id = id; manager = getNotificationManager(); var nativeNotification = createNativeNotification(context, notification); if (notification.Id == 909092) { //Remove ongoing notification that you have an active session manager.Cancel(909093); } manager.Notify(notification.Id, nativeNotification); wakeLock.Release(); } } private NotificationManager getNotificationManager() { var notificationManager = Application.Context.GetSystemService(Context.NotificationService) as NotificationManager; return notificationManager; } }
排查思路与解决建议
- 定位空值根源:从堆栈看,崩溃是因为
serializeFromString方法传入的字符串参数为null,导致StringReader初始化失败。需检查:- 设置定时通知时,是否确保传递给Intent的
LocalNotification_TITLE、LocalNotification_TEXT等参数无空值; - 应用被系统杀死后,Intent是否被系统重建导致部分Extra丢失。
- 设置定时通知时,是否确保传递给Intent的
- 强化空值校验:在
OnReceive中增加多层空值判断,避免后续逻辑因空值崩溃:if (intent == null || !intent.HasExtra(LocalNotificationKeyID) || string.IsNullOrEmpty(intent.GetStringExtra(LocalNotificationKeyTitle)) || string.IsNullOrEmpty(intent.GetStringExtra(LocalNotificationKeyText))) { wakeLock?.Release(); return; } - 修复NotificationManager获取逻辑:避免使用
Application.Context(应用被杀后可能为空),改用传入的context获取服务:
调用时传入private NotificationManager getNotificationManager(Context context) { return context.GetSystemService(Context.NotificationService) as NotificationManager; }context:manager = getNotificationManager(context); - 安全处理WakeLock:使用空值运算符确保
Release不会触发空指针异常,改为wakeLock?.Release(); - 复现测试:在应用后台、进程被杀状态下触发定时通知,通过Logcat查看实时日志,或结合Crashlytics查看崩溃设备的型号、Android版本分布,排查是否存在机型适配问题。
- 检查插件版本:若使用第三方LocalNotifications插件,查看是否有新版本修复了空值相关Bug,或检索插件的Issue列表是否有同类问题。
内容的提问来源于stack exchange,提问作者Spire
相关产品推荐
相关产品推荐

