Google Play预启动报告检测到.NET MAUI应用Java空引用异常
.NET MAUI应用Google Play预启动报告空引用异常排查与解决
我用.NET MAUI开发的应用在Debug和Release模式下运行均无异常,但上传至Google Play后,Google Play Console预启动报告检测到一处Java层空引用异常,导致应用无法通过审核。
错误日志
at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V callback, IntPtr jnienv, IntPtr klazz) Exception android.runtime.JavaProxyThrowable: System.NullReferenceException: Object reference not set to an instance of an object at WakeUp.CreateAlarmPage.OnButtonClicked(Object sender, EventArgs e) at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state) at Android.App.SyncContext.<>c__DisplayClass2_0.<Post>b__0() at Java.Lang.Thread.RunnableImplementor.Run() at Java.Lang.IRunnableInvoker.n_Run(IntPtr jnienv, IntPtr native__this) at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V(_JniMarshal_PP_V callback, IntPtr jnienv, IntPtr klazz) at mono.java.lang.RunnableImplementor.n_run at mono.java.lang.RunnableImplementor.run (RunnableImplementor.java:31) at android.os.Handler.handleCallback (Handler.java:942) at android.os.Handler.dispatchMessage (Handler.java:99) at android.os.Looper.loopOnce (Looper.java:201) at android.os.Looper.loop (Looper.java:288) at android.app.ActivityThread.main (ActivityThread.java:7918) at java.lang.reflect.Method.invoke at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:936)
相关代码
private async void OnButtonClicked(object sender, EventArgs e) { PermissionStatus check; if (Android.OS.Build.VERSION.SdkInt < Android.OS.BuildVersionCodes.Tiramisu) { check = await Permissions.CheckStatusAsync<Permissions.StorageRead>(); if (check != PermissionStatus.Granted) { PermissionStatus request = await Permissions.RequestAsync<Permissions.StorageRead>(); if (request != PermissionStatus.Granted) { return; } } } var customFileType = new FilePickerFileType( new Dictionary<DevicePlatform, IEnumerable<string>> { { DevicePlatform.Android, new[] { "audio/aac", "audio/aacp", "audio/webm", "audio/x-mp4", "audio/x-m4a", "audio/mp4", "audio/m4a", "audio/wav", "audio/mpeg", "audio/ogg", "audio/x-flac" } }, } ); PickOptions options = new() { FileTypes = customFileType, }; var result = await FilePicker.Default.PickAsync(options); if (result != null) { Debug.WriteLine("FullPath: " + result.FullPath); mediaPlayer.Source = result.FullPath; _soundPath = result.FullPath; soundName.Text = result.FileName; } }
异常原因分析
从错误栈和代码来看,空引用异常大概率出在OnButtonClicked方法内的以下几个点:
mediaPlayer对象未完成初始化:页面加载时若未给mediaPlayer赋值,设置Source属性时会触发空引用。soundName控件未正确绑定:XAML中x:Name="soundName"的控件未与后台代码正确关联,访问Text属性时为空。FilePicker.Default极端情况下返回null:尽管官方文档说明默认实例不会为空,但预启动测试的特殊设备环境可能导致此情况。
解决方案
1. 确保mediaPlayer完成初始化
在页面的构造函数或OnAppearing方法中添加初始化逻辑,避免使用时为空:
protected override void OnAppearing() { base.OnAppearing(); mediaPlayer ??= new MediaPlayer(); // 根据实际业务逻辑调整初始化方式 }
2. 验证soundName控件绑定
- 检查XAML中对应的控件是否设置了正确的
x:Name="soundName"; - 清理解决方案并重新编译,确保XAML代码生成正常,后台能正确引用该控件。
3. 增加FilePicker.Default空判断
在调用PickAsync前先校验实例是否存在:
if (FilePicker.Default == null) { // 可添加用户提示,告知无法使用文件选择功能 return; } var result = await FilePicker.Default.PickAsync(options);
4. 全局空引用防护
对所有可能为空的对象使用空传播运算符?.,避免直接访问属性:
if (result != null) { Debug.WriteLine("FullPath: " + result.FullPath); mediaPlayer?.Source = result.FullPath; _soundPath = result.FullPath; soundName?.Text = result.FileName; }
额外建议
模拟预启动测试的边界场景,比如权限被拒绝、取消文件选择等,验证代码鲁棒性,确保覆盖所有异常分支。
内容的提问来源于stack exchange,提问作者Metehan Ö.
相关产品推荐
相关产品推荐

