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

.NET 6 MAUI中Shell应用与WebView双向通信实现及Xamarin代码迁移问题咨询

.NET MAUI中WebView与JavaScript双向互操作的实现方案

你提到的问题很典型——MAUI确实摒弃了Xamarin.Forms里的Renderer模式,改用更灵活的Handler架构,所以原来的WebViewRenderer等类不再适用,但完全可以实现双向通信的功能,下面是针对Android平台的可行方案:

1. 创建自定义HybridWebView控件

先定义一个继承自MAUI WebView的自定义控件,用来封装JS消息接收和调用JS的能力:

using Microsoft.Maui.Controls;

namespace YourNamespace
{
    public class HybridWebView : WebView
    {
        // 用于接收JS传递的消息
        public static readonly BindableProperty MessageReceivedProperty =
            BindableProperty.Create(nameof(MessageReceived), typeof(Action<string>), typeof(HybridWebView));

        public Action<string> MessageReceived
        {
            get => (Action<string>)GetValue(MessageReceivedProperty);
            set => SetValue(MessageReceivedProperty, value);
        }

        // 调用JS方法的异步方法
        public async Task EvaluateJavaScriptAsync(string script)
        {
            await Handler.InvokeAsync("EvaluateJavaScript", script);
        }
    }
}

2. 实现Android平台的自定义Handler

MAUI用Handler替代了Renderer,我们需要创建HybridWebViewHandler来处理Android端的WebView配置:

2.1 编写JS桥接类(JsBridge)

这个类和你之前的JsBridge逻辑类似,但要适配MAUI的Handler:

using Android.Webkit;
using Java.Interop;

namespace YourNamespace.Platforms.Android
{
    public class JsBridge : Java.Lang.Object
    {
        private readonly WeakReference<HybridWebViewHandler> _handlerReference;

        public JsBridge(HybridWebViewHandler handler)
        {
            _handlerReference = new WeakReference<HybridWebViewHandler>(handler);
        }

        [JavascriptInterface]
        [Export("invokeCSharpAction")]
        public void InvokeAction(string data)
        {
            if (_handlerReference.TryGetTarget(out var handler) && handler.VirtualView is HybridWebView hybridWebView)
            {
                // 将JS消息传递给自定义控件的回调
                hybridWebView.MessageReceived?.Invoke(data);
            }
        }
    }
}

2.2 自定义WebViewClient

用来在页面加载完成后注入JS桥接函数:

using Android.Webkit;

namespace YourNamespace.Platforms.Android
{
    public class HybridWebViewClient : WebViewClient
    {
        private const string JsBridgeScript = "function invokeCSharpAction(data){jsBridge.invokeCSharpAction(data);}";

        public override void OnPageFinished(WebView view, string url)
        {
            base.OnPageFinished(view, url);
            // 注入JS函数,让网页可以调用C#代码
            view.EvaluateJavascript(JsBridgeScript, null);
        }
    }
}

2.3 实现HybridWebViewHandler

继承自MAUI的WebViewHandler,配置WebView并绑定桥接:

using Microsoft.Maui.Handlers;
using Android.Webkit;

namespace YourNamespace.Platforms.Android
{
    public class HybridWebViewHandler : WebViewHandler
    {
        // 继承MAUI默认的属性映射,可按需扩展
        public static IPropertyMapper<IWebView, WebViewHandler> HybridMapper =
            new PropertyMapper<IWebView, WebViewHandler>(WebViewHandler.Mapper);

        public HybridWebViewHandler() : base(HybridMapper, CommandMapper)
        {
        }

        protected override WebView CreatePlatformView()
        {
            var webView = base.CreatePlatformView();
            
            // 启用JavaScript
            webView.Settings.JavaScriptEnabled = true;
            // 设置自定义WebViewClient
            webView.SetWebViewClient(new HybridWebViewClient());
            // 添加JS桥接接口
            webView.AddJavascriptInterface(new JsBridge(this), "jsBridge");
            
            return webView;
        }

        // 实现调用JS的方法,供自定义控件调用
        public void EvaluateJavaScript(string script)
        {
            PlatformView?.EvaluateJavascript(script, null);
        }
    }
}

3. 注册Handler到MAUI应用

在MauiProgram.cs中注册自定义Handler:

using Microsoft.Maui;
using Microsoft.Maui.Hosting;
using YourNamespace.Platforms.Android;

namespace YourNamespace
{
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureMauiHandlers(handlers =>
                {
#if ANDROID
                    // 注册Android平台的自定义Handler
                    handlers.AddHandler<HybridWebView, HybridWebViewHandler>();
#endif
                });

            return builder.Build();
        }
    }
}

4. 使用自定义HybridWebView

在XAML中引用控件:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:YourNamespace"
             x:Class="YourNamespace.MainPage">

    <local:HybridWebView x:Name="MyHybridWebView" 
                         Source="https://your-web-page-url" />
</ContentPage>

在代码后台处理消息和调用JS:

using Microsoft.Maui.Controls;

namespace YourNamespace
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            
            // 监听JS传来的消息
            MyHybridWebView.MessageReceived += (data) =>
            {
                MainThread.BeginInvokeOnMainThread(() =>
                {
                    // 在UI线程处理消息
                    DisplayAlert("Received from JS", data, "OK");
                });
            };
        }

        // 示例:调用JS方法
        private async void CallJavaScriptButton_Clicked(object sender, EventArgs e)
        {
            await MyHybridWebView.EvaluateJavaScriptAsync("showMessage('Hello from MAUI!')");
        }
    }
}

补充说明

  • 这个方案在MAUI正式版及预览后期版本都能正常工作,Handler是MAUI的核心扩展机制,完全替代了原有的Renderer模式
  • 如果需要支持iOS平台,思路类似:使用WKWebView的WKScriptMessageHandler来实现双向通信,同样通过自定义Handler配置
  • 注意在Android中,[JavascriptInterface]和[Export]属性需要确保正确引用Java.Interop包

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 05:47:46