Xamarin.Forms 5.0 跨平台实现带初始化任务启动页并解决界面卡顿咨询
解决方案
首先明确问题答案
你需求的这类业务初始化阶段的启动页完全可以在Xamarin.Forms公共主应用层实现,无需修改Android、iOS平台专属项目的配置。你当前遇到的空白、卡顿问题,核心是代码阻塞了UI线程,需要同时做「新增公共层启动页」和「调整初始化逻辑为异步非阻塞」两个修改,二者缺一不可。
问题根因
你当前在OnStart方法中使用了Task.Run(...).Wait(),Wait()方法会同步阻塞当前UI线程,导致界面无法完成绘制,一直处于空白状态,哪怕先加了启动页,只要UI线程被阻塞,同样无法正常显示Logo和加载提示。
具体实现步骤
1. 新增公共层启动页
在共享项目中新建SplashPage.xaml,作为启动时展示的页面,包含你的品牌Logo、加载提示文本、加载动画:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="YourNamespace.SplashPage"> <StackLayout VerticalOptions="Center" HorizontalOptions="Center"> <!-- 品牌Logo --> <Image Source="your_logo.png" HeightRequest="150" WidthRequest="150" /> <!-- 加载提示 --> <Label Text="数据加载中..." Margin="0,20,0,10" HorizontalOptions="Center" /> <!-- 滚动加载动画 --> <ActivityIndicator IsRunning="True" HorizontalOptions="Center" /> </StackLayout> </ContentPage>
然后编写SplashPage.xaml.cs的后台逻辑,在页面显示后异步执行初始化任务,完成后切换到主应用页面:
public partial class SplashPage : ContentPage { public SplashPage() { InitializeComponent(); // 禁止用户返回跳过启动页 NavigationPage.SetHasNavigationBar(this, false); } protected override async void OnAppearing() { base.OnAppearing(); // 异步执行初始化逻辑,不阻塞UI线程 if (App.Database != null) { // 同步的建表逻辑包在Task.Run中放到后台线程执行 await Task.Run(() => App.Database.CreateTables()); // 直接await异步拉取数据方法,不需要再包Task.Run+Wait await App._MyDataStore.PullDataFromAPI(); } // 所有任务完成后切换到主应用 Application.Current.MainPage = new AppShell(); } // 屏蔽物理返回键,禁止用户跳过启动页 protected override bool OnBackButtonPressed() { return true; } }
2. 修改App.xaml.cs逻辑
删除OnStart方法中原有的初始化逻辑,修改构造函数的默认启动页面为SplashPage:
public partial class App : Application { static Database database; public IMyDataStore<MyViewPagesModel> _MyDataStore=> DependencyService.Get<IMyDataStore<MyViewPagesModel>>(); public static Database Database { get { if (database == null) { database = new Database(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "my_db.db3")); } return database; } } public App() { InitializeComponent(); DependencyService.Register<MyDataStore>(); // 启动页设为默认页面,不再直接加载AppShell MainPage = new SplashPage(); } protected override void OnStart() { // 原有初始化逻辑已移到SplashPage,此处留空即可 } }
补充说明
如果你需要优化系统加载应用进程阶段的空白体验(也就是用户点击应用图标到Xamarin.Forms框架初始化完成这段时间的空白),才需要单独配置Android和iOS的原生启动屏,你当前的业务初始化需求用上面的公共层启动页即可完全满足。
内容的提问来源于stack exchange,提问作者jason
相关产品推荐
相关产品推荐

