有没有办法在 .NET 6 MAUI 中创建 shell 应用程序和 Web 视图之间的双向通信?
Is there a way to create bi-directional communication between a shell app and a webview in .NET 6 MAUI?
最近我的任务是在 shell 应用程序和 .NET MAUI 中的网页之间创建双向互操作桥。找不到任何方法来解决这个问题,我想到了在 Xamarin.Forms 中创建它,首先看到 MAUI 是它的延续。
创建此应用程序后,我尝试使用 Microsoft 在 dotnet/maui github wiki 上的说明将其转换为 MAUI。
我现在遇到的主要问题是我一直在 Android 的 WebViewRenderer、WebViewClient[= 上使用扩展27=] 和 Java.Lang.Object 能够向 WebView 发送和接收 javascript。
public class ExtendedWebViewRenderer : WebViewRenderer
{
private const String JavascriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";
public ExtendedWebViewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
Control.RemoveJavascriptInterface("jsBridge");
((ExtendedWebView)Element).Cleanup();
}
if (e.NewElement != null)
{
Control.SetWebViewClient(new JavascriptWebViewClient($"javascript: {JavascriptFunction}"));
Control.AddJavascriptInterface(new JsBridge(this), "jsBridge");
}
}
}
public class JavascriptWebViewClient : WebViewClient
{
private readonly String _javascript;
public JavascriptWebViewClient(String javascript)
{
_javascript = javascript;
}
public override void OnPageFinished(WebView view, String url)
{
base.OnPageFinished(view, url);
view.EvaluateJavascript(_javascript, null);
}
}
public class JsBridge : Java.Lang.Object
{
private readonly WeakReference<ExtendedWebViewRenderer> _extendedWebViewMainRenderer;
public JsBridge(ExtendedWebViewRenderer extendedRenderer)
{
_extendedWebViewMainRenderer = new WeakReference<ExtendedWebViewRenderer>(extendedRenderer);
}
[JavascriptInterface]
[Export("invokeAction")]
public void InvokeAction(String data)
{
if (_extendedWebViewMainRenderer != null && _extendedWebViewMainRenderer.TryGetTarget(out var extendedRenderer))
{
((ExtendedWebView)extendedRenderer.Element).InvokeAction(data);
}
}
}
这三者要么现在不可用,要么不会在 MAUI 中实现,因为许多平台相关代码现在已经自动化。这给我留下了一个问题,我似乎无法弄清楚如何更改我当前的代码以在 MAUI 中完成同样的事情。
鉴于 MAUI 目前甚至还没有完全发布,我想知道目前这是不可能的,还是有一些解决方法可以实现。
如有任何帮助,我们将不胜感激。
MAUI 的默认 WebView
具有 Eval
和 EvaluateJavaScriptAsync
函数以从 C# 调用 JavaScript 代码:
Eval
只是执行脚本 string
您以即发即弃的方式传递的脚本。
EvaluateJavaScriptAsync
需要等待 returns string
,其中包含脚本返回的数据的字符串化结果。
如果您想使用 callback/bridge 方法自动接收来自 JavaScript 端的数据,而无需来自应用程序 C# 端的任何输入,您将必须扩展默认的每平台渲染器添加该功能。好消息是,在 Customizing a WebView which is almost straightforward to port to .NET MAUI - you only have to change how renderers are registered.
上有一个关于如何为 Xamarin Forms 执行此操作的官方教程
最近我的任务是在 shell 应用程序和 .NET MAUI 中的网页之间创建双向互操作桥。找不到任何方法来解决这个问题,我想到了在 Xamarin.Forms 中创建它,首先看到 MAUI 是它的延续。
创建此应用程序后,我尝试使用 Microsoft 在 dotnet/maui github wiki 上的说明将其转换为 MAUI。
我现在遇到的主要问题是我一直在 Android 的 WebViewRenderer、WebViewClient[= 上使用扩展27=] 和 Java.Lang.Object 能够向 WebView 发送和接收 javascript。
public class ExtendedWebViewRenderer : WebViewRenderer
{
private const String JavascriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";
public ExtendedWebViewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
Control.RemoveJavascriptInterface("jsBridge");
((ExtendedWebView)Element).Cleanup();
}
if (e.NewElement != null)
{
Control.SetWebViewClient(new JavascriptWebViewClient($"javascript: {JavascriptFunction}"));
Control.AddJavascriptInterface(new JsBridge(this), "jsBridge");
}
}
}
public class JavascriptWebViewClient : WebViewClient
{
private readonly String _javascript;
public JavascriptWebViewClient(String javascript)
{
_javascript = javascript;
}
public override void OnPageFinished(WebView view, String url)
{
base.OnPageFinished(view, url);
view.EvaluateJavascript(_javascript, null);
}
}
public class JsBridge : Java.Lang.Object
{
private readonly WeakReference<ExtendedWebViewRenderer> _extendedWebViewMainRenderer;
public JsBridge(ExtendedWebViewRenderer extendedRenderer)
{
_extendedWebViewMainRenderer = new WeakReference<ExtendedWebViewRenderer>(extendedRenderer);
}
[JavascriptInterface]
[Export("invokeAction")]
public void InvokeAction(String data)
{
if (_extendedWebViewMainRenderer != null && _extendedWebViewMainRenderer.TryGetTarget(out var extendedRenderer))
{
((ExtendedWebView)extendedRenderer.Element).InvokeAction(data);
}
}
}
这三者要么现在不可用,要么不会在 MAUI 中实现,因为许多平台相关代码现在已经自动化。这给我留下了一个问题,我似乎无法弄清楚如何更改我当前的代码以在 MAUI 中完成同样的事情。
鉴于 MAUI 目前甚至还没有完全发布,我想知道目前这是不可能的,还是有一些解决方法可以实现。
如有任何帮助,我们将不胜感激。
MAUI 的默认 WebView
具有 Eval
和 EvaluateJavaScriptAsync
函数以从 C# 调用 JavaScript 代码:
Eval
只是执行脚本string
您以即发即弃的方式传递的脚本。EvaluateJavaScriptAsync
需要等待 returnsstring
,其中包含脚本返回的数据的字符串化结果。
如果您想使用 callback/bridge 方法自动接收来自 JavaScript 端的数据,而无需来自应用程序 C# 端的任何输入,您将必须扩展默认的每平台渲染器添加该功能。好消息是,在 Customizing a WebView which is almost straightforward to port to .NET MAUI - you only have to change how renderers are registered.
上有一个关于如何为 Xamarin Forms 执行此操作的官方教程