MAUI中如何监听浏览器关闭?实现等待关闭后执行后续操作
MAUI中等待浏览器关闭后执行后续逻辑的解决方案
MAUI自带的Browser.Default.OpenAsync仅在浏览器启动完成后就继续执行代码,不会等待用户关闭页面。要实现等待用户完成操作(比如Stripe支付)并关闭浏览器后再执行后续逻辑,可采用以下两种方案:
方案一:使用嵌入式WebView控制页面生命周期
通过在应用内嵌入WebView,直接监听页面导航事件,在支付完成的回调URL触发时结束等待。
实现步骤
- 在XAML页面中添加WebView控件:
<WebView x:Name="PaymentWebView" IsVisible="False" />
- 后台代码中处理导航逻辑并等待完成:
private async Task<string> HandleNoFunds() { if (!HasAcceptedStripeTerms) { // 处理Stripe条款展示逻辑 } var completionSource = new TaskCompletionSource<string>(); // 监听WebView导航事件,判断支付状态 PaymentWebView.Navigated += (sender, args) => { // 假设Stripe支付成功后会跳转到包含"payment_success"的URL if (args.Url.Contains("payment_success")) { PaymentWebView.IsVisible = false; completionSource.SetResult("success"); } // 处理取消支付的情况 else if (args.Url.Contains("payment_cancel")) { PaymentWebView.IsVisible = false; completionSource.SetResult("cancel"); } }; // 显示WebView并导航到支付页面 PaymentWebView.IsVisible = true; PaymentWebView.Source = myStripeCustomPageUrl; // 等待支付流程结束 var result = await completionSource.Task; return result; }
优缺点:跨平台逻辑统一,容易自定义交互;但缺少系统浏览器的原生特性(如自动填充、安全验证),用户体验略有折扣。
方案二:平台特定的浏览器关闭监听
利用MAUI的依赖注入能力,为各平台实现系统浏览器的关闭回调,保留系统浏览器的原生体验。
实现步骤
- 定义跨平台接口:
public interface ICustomBrowser { Task<string> OpenAsync(string url); }
- Android平台实现(使用CustomTabs):
[assembly: Dependency(typeof(CustomBrowserAndroid))] namespace YourAppNamespace.Droid { public class CustomBrowserAndroid : ICustomBrowser { public async Task<string> OpenAsync(string url) { var completionSource = new TaskCompletionSource<string>(); var customTabsIntent = new AndroidX.Browser.CustomTabs.CustomTabsIntent.Builder().Build(); var serviceConnection = new CustomTabServiceConnection(completionSource); Application.Context.BindService( new Intent(Application.Context, typeof(CustomTabService)), serviceConnection, Bind.AutoCreate); customTabsIntent.LaunchUrl(Application.Context, Android.Net.Uri.Parse(url)); return await completionSource.Task; } private class CustomTabServiceConnection : IServiceConnection { private readonly TaskCompletionSource<string> _completionSource; public CustomTabServiceConnection(TaskCompletionSource<string> completionSource) { _completionSource = completionSource; } public void OnServiceConnected(ComponentName name, IBinder service) { var customTabService = AndroidX.Browser.CustomTabs.ICustomTabsService.Stub.AsInterface(service); var callback = new CustomTabCallback(_completionSource); customTabService.Warmup(0); customTabService.NewSession(callback); } public void OnServiceDisconnected(ComponentName name) { _completionSource.TrySetResult("closed"); } private class CustomTabCallback : AndroidX.Browser.CustomTabs.CustomTabsCallback { private readonly TaskCompletionSource<string> _completionSource; public CustomTabCallback(TaskCompletionSource<string> completionSource) { _completionSource = completionSource; } public override void OnNavigationEvent(int navigationEvent, Bundle extras) { if (navigationEvent == CustomTabsCallback.NavigationEventTabClosed) { _completionSource.TrySetResult("closed"); } } } } } }
- iOS平台实现(使用SFSafariViewController):
[assembly: Dependency(typeof(CustomBrowseriOS))] namespace YourAppNamespace.iOS { public class CustomBrowseriOS : ICustomBrowser { public async Task<string> OpenAsync(string url) { var completionSource = new TaskCompletionSource<string>(); var safariVC = new SafariServices.SFSafariViewController(new NSUrl(url)); safariVC.DidFinish += (sender, args) => { completionSource.SetResult("closed"); safariVC.DismissViewController(true, null); }; var keyWindow = UIApplication.SharedApplication.ConnectedScenes .OfType<UIWindowScene>() .FirstOrDefault()? .Windows .FirstOrDefault(w => w.IsKeyWindow); keyWindow?.RootViewController.PresentViewController(safariVC, true, null); return await completionSource.Task; } } }
- MAUI项目中调用自定义浏览器:
private async Task<string> HandleNoFunds() { if (!HasAcceptedStripeTerms) { // 处理Stripe条款展示逻辑 } var customBrowser = DependencyService.Get<ICustomBrowser>(); await customBrowser.OpenAsync(myStripeCustomPageUrl); // 浏览器关闭后才会执行后续代码 return "success"; }
优缺点:保留系统浏览器的全部原生特性,用户体验好;但需要编写各平台的专属代码,维护成本相对较高。
内容的提问来源于stack exchange,提问作者Mihai Vasile
相关产品推荐
相关产品推荐

