使用Xamarin.Forms.Application.Current.Properties与Android AppWidgetProvider遇空指针异常
问题根源分析
你的核心问题在于混淆了Xamarin.Forms应用与Android原生AppWidget的生命周期边界:
- Xamarin.Forms.Application.Current只有在Forms应用完成初始化(也就是
LoadApplication(new App())执行后)才会有值; - 而Android的AppWidgetProvider是完全独立的原生组件,系统可以在你的主应用进程被杀死后,单独唤醒Widget进程来执行更新逻辑,这时候Forms应用根本没被初始化,
Application.Current自然就是null,直接访问就会触发空指针异常。
所以你的做法确实存在适配性问题,用Forms的Properties来存储Widget相关数据本身就不合适。
解决方案
1. 改用Android原生存储方案(推荐)
既然是Android Widget,直接用Android原生的SharedPreferences来存储数据是最稳妥的,完全不依赖Forms的生命周期,适配性拉满:
// 存储JSON数据 var prefs = Application.Context.GetSharedPreferences("WidgetData", FileCreationMode.Private); var editor = prefs.Edit(); editor.PutString("SavedJson", yourJsonContent); editor.Apply(); // 读取JSON数据 var prefs = Application.Context.GetSharedPreferences("WidgetData", FileCreationMode.Private); var savedJson = prefs.GetString("SavedJson", string.Empty);
2. 强制Forms在Widget进程启动时初始化(应急方案)
如果一定要沿用Forms的Properties,你可以在Android的全局Application类(不是Forms的App)中初始化Forms,这样只要进程启动(不管是主应用还是Widget触发),Forms都会被初始化,保证Application.Current不为null:
- 第一步:自定义Android Application类
[Application] public class MyAndroidApp : Android.App.Application { public MyAndroidApp(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) { } public override void OnCreate() { base.OnCreate(); // 初始化Forms框架,进程启动时仅执行一次 Xamarin.Forms.Forms.Init(this, null); // 确保Forms App实例存在,避免Current为空 if (Xamarin.Forms.Application.Current == null) { _ = new App(); // 初始化你的Forms应用实例 } } }
- 第二步:在AndroidManifest.xml中指定这个自定义Application类
<application android:name=".MyAndroidApp" ...> <!-- 其他原有配置 --> </application>
⚠️ 注意:这种方式会增加Widget进程的内存开销,因为要加载整个Forms框架,仅推荐在迫不得已的场景使用。
3. 全局空安全防护
不管用哪种方案,都要给关键代码加空判断,避免空指针崩溃:
// 访问Forms Properties前先做空检查 if (Xamarin.Forms.Application.Current != null && Xamarin.Forms.Application.Current.Properties.ContainsKey("SavedJson")) { var jsonData = Xamarin.Forms.Application.Current.Properties["SavedJson"]; // 处理数据逻辑 } else { // 降级处理,比如从SharedPreferences读取默认值 }
总结
优先推荐用Android原生的SharedPreferences来存储Widget相关数据,这是最贴合Android组件生命周期的方案。如果一定要用Forms的Properties,记得在全局Application类中提前初始化Forms,同时做好空安全检查,避免崩溃。
内容的提问来源于stack exchange,提问作者kaolick
相关产品推荐
相关产品推荐

