Xamarin.Forms深色模式启动触发PlatformConfigurationExtensions.cs空引用异常
Xamarin.Forms 强制浅色模式深色设备启动空引用异常修复
问题复现条件
- 项目中添加代码强制应用使用浅色模式:
AppCompatDelegate.DefaultNightMode = AppCompatDelegate.ModeNightNo;
- 设备系统开启深色模式时启动应用必现崩溃,浅色模式下应用启动、运行完全正常
- 崩溃抛出异常为
System.NullReferenceException: Object reference not set to an instance of an object.,抛出点位于Xamarin.Forms安卓平台的PlatformConfigurationExtensions.cs第8行 - 异常堆栈:
at Xamarin.Forms.Platform.Android.PlatformConfigurationExtensions.OnThisPlatform[T] (T element) [0x00000] in D:\a\1\s\Xamarin.Forms.Platform.Android\PlatformConfigurationExtensions.cs:8 at Xamarin.Forms.Platform.Android.AppCompat.FragmentContainer.OnResume () [0x00007] in D:\a\1\s\Xamarin.Forms.Platform.Android\AppCompat\FragmentContainer.cs:126 at AndroidX.Fragment.App.Fragment.n_OnResume (System.IntPtr jnienv, System.IntPtr native__this) [0x00008] in D:\a\1\s\generated\androidx.fragment.fragment\obj\Release\monoandroid9.0\generated\src\AndroidX.Fragment.App.Fragment.cs:2548 at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.115(intptr,intptr)
- 调试时崩溃点所有线程均显示执行外部代码,无法直接断点定位业务侧问题
根因说明
崩溃本质是夜间模式设置时机过晚,触发了Activity异常重建。
如果在base.OnCreate执行后、或者Xamarin.Forms初始化流程中才修改DefaultNightMode,安卓系统会自动销毁当前已创建的Activity实例,按新的模式重新走生命周期。此时Xamarin.Forms的Fragment恢复执行OnResume时,关联的Platform渲染实例已经被销毁,OnThisPlatform扩展方法获取不到有效实例就会抛出空引用。
修复方案
按以下步骤调整即可100%解决问题:
- 优先把夜间模式配置放到Application类的OnCreate最前端
如果安卓项目有自定义MainApplication类,直接在OnCreate里、所有其他初始化逻辑之前设置模式,这是最稳妥的方案,能覆盖所有Activity启动场景:[Application] public class MainApplication : Application { public MainApplication(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer) { } public override void OnCreate() { // 第一行就设置,早于所有初始化逻辑 AppCompatDelegate.DefaultNightMode = AppCompatDelegate.ModeNightNo; base.OnCreate(); // 其他原有初始化逻辑保留 } } - 没有自定义Application类的话,就把设置逻辑放到
MainActivity的OnCreate最开头,必须在base.OnCreate(savedInstanceState)调用之前执行,不能放在Xamarin.Forms初始化之后:protected override void OnCreate(Bundle savedInstanceState) { // 注意位置:在base.OnCreate之前 AppCompatDelegate.DefaultNightMode = AppCompatDelegate.ModeNightNo; base.OnCreate(savedInstanceState); Xamarin.Essentials.Platform.Init(this, savedInstanceState); global::Xamarin.Forms.Forms.Init(this, savedInstanceState); LoadApplication(new App()); } - 补充主题配置做双重兼容:打开安卓项目的
Resources/values/styles.xml,在应用主题节点下添加强制禁用深色自动适配的配置,避免系统强制给页面套深色模式触发重建:<style name="MainTheme" parent="MainTheme.Base"> <!-- 原有主题配置保留不变 --> <item name="android:forceDarkAllowed">false</item> </style>
避坑提醒:不要在Xamarin.Forms共享层(比如App.xaml.cs、页面生命周期里)调用安卓专属的
AppCompatDelegate配置,这类原生端配置必须在安卓原生生命周期最早期执行才会生效。
内容的提问来源于stack exchange,提问作者SarPa
相关产品推荐
相关产品推荐

