解决Xamarin Forms中Android 12的启动页重复显示问题
Xamarin Forms Android 12启动页重复显示问题解决方案
问题根源分析
- SplashActivity生命周期方法重载错误:原代码使用带
PersistableBundle参数的OnCreate重载,默认启动流程不会触发该方法,导致页面初始化逻辑缺失,引发生命周期异常。 - Android 12启动页规范未适配:API 31+引入了全新的Splash Screen API,旧的
windowBackground方式会与系统默认启动页叠加,造成重复显示。 - 主题配置矛盾:原启动页主题父类为
Theme.AppCompat.Light.NoActionBar,却又设置android:windowActionBar="true",引发主题冲突。 - 页面跳转逻辑不严谨:启动MainActivity时未设置正确的Intent Flags,也未主动销毁SplashActivity,导致页面残留。
具体修复步骤
1. 修正SplashActivity代码
namespace Splash12.Droid { [Activity(Theme = "@style/MyTheme.Splash", MainLauncher = true, NoHistory = true, LaunchMode = LaunchMode.SingleTop)] public class SplashActivity : AppCompatActivity { static readonly string TAG = "X:" + typeof(SplashActivity).Name; // 使用默认的OnCreate重载,确保启动时触发 protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); Log.Debug(TAG, "SplashActivity.OnCreate"); } protected override void OnResume() { base.OnResume(); _ = Task.Run(async () => await SimulateStartup()); } async Task SimulateStartup() { Log.Debug(TAG, "Performing startup work."); await Task.Delay(2000); // 替换为真实初始化逻辑 Log.Debug(TAG, "Startup work finished - launching MainActivity."); var intent = new Intent(Application.Context, typeof(MainActivity)); // 清除栈顶,避免重复实例化 intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.SingleTop); StartActivity(intent); Finish(); // 主动销毁SplashActivity,防止残留 } } }
2. 适配Android 12启动页主题
低版本兼容主题(res/values/styles.xml)
<style name="MyTheme.Splash" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowBackground">@drawable/splash_screen</item> <item name="android:windowNoTitle">true</item> <item name="android:windowFullscreen">true</item> <item name="android:windowContentOverlay">@null</item> </style>
Android 12专属主题(res/values-v31/styles.xml)
<style name="MyTheme.Splash" parent="Theme.SplashScreen"> <!-- 启动页背景色 --> <item name="windowSplashScreenBackground">@color/splash_background</item> <!-- 启动页图标 --> <item name="windowSplashScreenAnimatedIcon">@drawable/splash_screen</item> <!-- 图标动画时长(无需动画可设为0) --> <item name="windowSplashScreenAnimationDuration">200</item> <!-- 指定跳转后的Activity主题 --> <item name="postSplashScreenTheme">@style/MainTheme</item> </style>
3. 更新MainActivity适配系统启动页
[Activity(Label = "Splash12", Theme = "@style/MainTheme", Icon = "@mipmap/icon", MainLauncher = false, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize )] public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity { protected override void OnCreate(Bundle savedInstanceState) { // 适配Android 12系统启动页,完成初始化后自动隐藏 if (Build.VERSION.SdkInt >= BuildVersionCodes.S) { var splashScreen = SplashScreen.InstallSplashScreen(this); splashScreen.SetKeepOnScreenCondition(() => false); } base.OnCreate(savedInstanceState); Xamarin.Essentials.Platform.Init(this, savedInstanceState); global::Xamarin.Forms.Forms.Init(this, savedInstanceState); LoadApplication(new App()); } public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults) { Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults); base.OnRequestPermissionsResult(requestCode, permissions, grantResults); } }
4. 规范splash_screen.xml结构(示例)
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@color/splash_background"/> <item> <bitmap android:gravity="center" android:src="@mipmap/ic_launcher"/> </item> </layer-list>
内容的提问来源于stack exchange,提问作者nike
相关产品推荐
相关产品推荐

