You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在MAUI 6/7中创建自定义WebView,实现加载监测与错误处理

在MAUI中实现WebView的加载状态与错误监测(Android平台)

步骤1:创建自定义MAUI WebView(推荐)

在共享项目中定义继承自Microsoft.Maui.Controls.WebView的自定义控件,用来传递Android端的状态回调:

using Microsoft.Maui.Controls;

namespace YourAppNamespace
{
    public class CustomMauiWebView : WebView
    {
        // 加载完成事件
        public event EventHandler<string> PageLoaded;
        // 加载错误事件
        public event EventHandler<WebViewErrorEventArgs> PageLoadFailed;
        // 加载超时事件
        public event EventHandler<string> PageLoadTimeout;

        // 触发加载完成回调
        public void OnPageLoaded(string url)
        {
            PageLoaded?.Invoke(this, url);
        }

        // 触发加载错误回调
        public void OnPageLoadFailed(string url, int errorCode, string description)
        {
            PageLoadFailed?.Invoke(this, new WebViewErrorEventArgs(url, errorCode, description));
        }

        // 触发超时回调
        public void OnPageLoadTimeout(string url)
        {
            PageLoadTimeout?.Invoke(this, url);
        }
    }

    // 错误事件参数类
    public class WebViewErrorEventArgs : EventArgs
    {
        public string Url { get; }
        public int ErrorCode { get; }
        public string Description { get; }

        public WebViewErrorEventArgs(string url, int errorCode, string description)
        {
            Url = url;
            ErrorCode = errorCode;
            Description = description;
        }
    }
}

步骤2:在Android项目中实现自定义WebViewHandler

在Android项目中创建Handler,关联MAUI控件与原生WebView,并设置自定义WebViewClient:

using Android.Webkit;
using Microsoft.Maui.Controls.Platform;
using YourAppNamespace;
using YourAppNamespace.Platforms.Android;
using System.Threading;

[assembly: ExportHandler(typeof(CustomMauiWebView), typeof(CustomWebViewHandler))]
namespace YourAppNamespace.Platforms.Android
{
    public class CustomWebViewHandler : WebViewHandler
    {
        private CustomWebViewClient _customWebViewClient;
        private Timer _loadTimeoutTimer;
        private const int LoadTimeoutMilliseconds = 30000; // 30秒超时阈值

        protected override Android.Webkit.WebView CreatePlatformView()
        {
            var webView = base.CreatePlatformView();
            _customWebViewClient = new CustomWebViewClient(this);
            webView.SetWebViewClient(_customWebViewClient);
            return webView;
        }

        protected override void ConnectHandler(Android.Webkit.WebView platformView)
        {
            base.ConnectHandler(platformView);
            // 监听加载开始事件,启动超时定时器
            platformView.LoadStarted += OnLoadStarted;
        }

        protected override void DisconnectHandler(Android.Webkit.WebView platformView)
        {
            platformView.LoadStarted -= OnLoadStarted;
            _loadTimeoutTimer?.Dispose();
            base.DisconnectHandler(platformView);
        }

        private void OnLoadStarted(object sender, string e)
        {
            // 重置超时定时器
            _loadTimeoutTimer?.Dispose();
            _loadTimeoutTimer = new Timer(_ =>
            {
                ((CustomMauiWebView)VirtualView).OnPageLoadTimeout(e);
                _loadTimeoutTimer?.Dispose();
            }, null, LoadTimeoutMilliseconds, Timeout.Infinite);
        }

        // 自定义WebViewClient,处理加载完成与错误
        public class CustomWebViewClient : WebViewClient
        {
            private readonly CustomWebViewHandler _handler;

            public CustomWebViewClient(CustomWebViewHandler handler)
            {
                _handler = handler;
            }

            public override void OnPageFinished(Android.Webkit.WebView view, string url)
            {
                base.OnPageFinished(view, url);
                _handler._loadTimeoutTimer?.Dispose();
                ((CustomMauiWebView)_handler.VirtualView).OnPageLoaded(url);
            }

            public override void OnReceivedError(Android.Webkit.WebView view, IWebResourceRequest request, WebResourceError error)
            {
                base.OnReceivedError(view, request, error);
                _handler._loadTimeoutTimer?.Dispose();
                ((CustomMauiWebView)_handler.VirtualView).OnPageLoadFailed(
                    request.Url.ToString(), 
                    error.ErrorCode, 
                    error.DescriptionFormatted.ToString());
            }
        }
    }
}

步骤3:在MAUI页面中使用并监听状态

在XAML或代码中使用自定义WebView,处理状态回调:

XAML示例

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YourAppNamespace"
             x:Class="YourAppNamespace.MainPage">
    <local:CustomMauiWebView x:Name="customWebView"
                             Source="https://example.com"
                             PageLoaded="CustomWebView_PageLoaded"
                             PageLoadFailed="CustomWebView_PageLoadFailed"
                             PageLoadTimeout="CustomWebView_PageLoadTimeout"/>
</ContentPage>

代码后台示例

namespace YourAppNamespace
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void CustomWebView_PageLoaded(object sender, string e)
        {
            DisplayAlert("提示", $"页面 {e} 加载完成", "确定");
        }

        private void CustomWebView_PageLoadFailed(object sender, WebViewErrorEventArgs e)
        {
            DisplayAlert("错误", $"页面 {e.Url} 加载失败,错误码:{e.ErrorCode},描述:{e.Description}", "确定");
        }

        private void CustomWebView_PageLoadTimeout(object sender, string e)
        {
            DisplayAlert("超时", $"页面 {e} 加载超时", "确定");
            customWebView.StopLoading();
        }
    }
}

关键说明

  • MAUI通过Handler替代Xamarin的自定义渲染器,需用ExportHandler特性关联自定义控件与Handler。
  • 超时逻辑需手动实现:加载开始时启动定时器,加载完成/错误时取消定时器,定时器触发则判定为超时。
  • OnReceivedError会捕获WebView加载过程中的各类错误(如网络异常、404等)。

内容的提问来源于stack exchange,提问作者Ahad Porkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 02:44:54