Javascript 如何在xamarin的webview应用程序中从js运行c#方法
我在xamarin的webview中运行js中的c#方法时遇到问题 我有这样一个c#方法:Javascript 如何在xamarin的webview应用程序中从js运行c#方法,javascript,c#,android,xamarin,Javascript,C#,Android,Xamarin,我在xamarin的webview中运行js中的c#方法时遇到问题 我有这样一个c#方法: public void simpleMethod(int a、string b、bool c){ 字符串[]数据; 如果(c){ 数据[a]=b; } } 现在我如何从javasript调用此方法?您不需要。 基本上,您必须检测/触发一段javascript代码,使用C#webview配置/初始化代码进行检测,然后执行C# 看看android,了解我的意思,并在android上实现它。 对于iOS,您可
public void simpleMethod(int a、string b、bool c){
字符串[]数据;
如果(c){
数据[a]=b;
}
}
现在我如何从javasript调用此方法?您不需要。
基本上,您必须检测/触发一段javascript代码,使用C#webview配置/初始化代码进行检测,然后执行C#
看看android,了解我的意思,并在android上实现它。
对于iOS,您可以使用WKWebview侦听器从网页接收信息。您可以创建
WebView的自定义呈现程序
在表单中创建自定义WebView
公共类JSBridge:Java.Lang.Object
{
只读WeakReference hybridWebViewRenderer;
公共JSBridge(HybridWebViewRenderer hybridRenderer)
{
hybridWebViewRenderer=新的WeakReference(hybridRenderer);
}
[JavascriptInterface]
[导出(“调用”)]
公共void调用(int a、字符串b、bool c)
{
HybridWebViewRenderer hybridRenderer;
if(hybridWebViewRenderer!=null&&hybridWebViewRenderer.TryGetTarget(out hybridRenderer))
{
hybridRenderer.Element.InvokeAction(a、b、c);
}
}
}
默认情况下,Xamarin是否可以实现此功能?这将是很好的,这将是很好的,有类似的东西,而不必添加任何代码。
public class HybridWebView : View
{
Action<int, string, bool> action;
public static readonly BindableProperty UriProperty = BindableProperty.Create (
propertyName: "Uri",
returnType: typeof(string),
declaringType: typeof(HybridWebView),
defaultValue: default(string));
public string Uri {
get { return (string)GetValue (UriProperty); }
set { SetValue (UriProperty, value); }
}
public void RegisterAction (Action<int, string, bool> callback)
{
action = callback;
}
public void Cleanup ()
{
action = null;
}
public void InvokeAction (int a,string b,bool c)
{
if (action == null ) {
return;
}
action.Invoke (a,b,c);
}
}
public partial class xxxPage : ContentPage
{
public xxxPage ()
{
//...
hybridWebView.RegisterAction ((a,b,c) => simpleMethod(a,b,c));
}
public void simpleMethod(int a,string b,bool c)
{
string[] data;
if(c){
data[a] = b;
}
}
}
<ContentPage.Content>
<local:HybridWebView x:Name="hybridWebView" Uri="https://docs.microsoft.com"
HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
</ContentPage.Content>
<button type="button" onclick="javascript:invokeCSCode(a,b,c);">Invoke C# Code</button>
//...
<script type="text/javascript">
function invokeCSCode(a,b,c) {
try {
invokeCSharpAction(a,b,c);
}
catch (err){
log(err);
}
}
[assembly: ExportRenderer (typeof(HybridWebView), typeof(HybridWebViewRenderer))]
namespace CustomRenderer.iOS
{
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, WKWebView>, IWKScriptMessageHandler
{
const string JavaScriptFunction = "function invokeCSharpAction(a,b,c){window.webkit.messageHandlers.invokeAction.postMessage(a,b,c);}";
WKUserContentController userController;
protected override void OnElementChanged (ElementChangedEventArgs<HybridWebView> e)
{
base.OnElementChanged (e);
if (e.OldElement != null) {
userController.RemoveAllUserScripts ();
userController.RemoveScriptMessageHandler ("invokeAction");
var hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup ();
}
if (e.NewElement != null) {
if (Control == null) {
userController = new WKUserContentController ();
var script = new WKUserScript (new NSString (JavaScriptFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
userController.AddUserScript (script);
userController.AddScriptMessageHandler (this, "invokeAction");
var config = new WKWebViewConfiguration { UserContentController = userController };
var webView = new WKWebView (Frame, config);
SetNativeControl (webView);
}
Control.LoadRequest (new NSUrlRequest (new NSUrl (Element.Uri, false)));
}
}
public void DidReceiveScriptMessage (WKUserContentController userContentController, WKScriptMessage message)
{
Element.InvokeAction (message.Body.ToString ());
}
}
}
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
namespace CustomRenderer.Droid
{
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, Android.Webkit.WebView>
{
const string JavascriptFunction = "function invokeCSharpAction(a,b,c){jsBridge.invokeAction(a,b,c);}";
Context _context;
public HybridWebViewRenderer(Context context) : base(context)
{
_context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
Control.RemoveJavascriptInterface("jsBridge");
var hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup();
}
if (e.NewElement != null)
{
if (Control == null)
{
var webView = new Android.Webkit.WebView(_context);
webView.Settings.JavaScriptEnabled = true;
webView.SetWebViewClient(new JavascriptWebViewClient($"javascript: {JavascriptFunction}"));
SetNativeControl(webView);
}
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
Control.LoadUrl(Element.Uri);
}
}
}
}
public class JavascriptWebViewClient : WebViewClient
{
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
{
readonly WeakReference<HybridWebViewRenderer> hybridWebViewRenderer;
public JSBridge (HybridWebViewRenderer hybridRenderer)
{
hybridWebViewRenderer = new WeakReference <HybridWebViewRenderer> (hybridRenderer);
}
[JavascriptInterface]
[Export ("invokeAction")]
public void InvokeAction (int a,string b,bool c)
{
HybridWebViewRenderer hybridRenderer;
if (hybridWebViewRenderer != null && hybridWebViewRenderer.TryGetTarget (out hybridRenderer))
{
hybridRenderer.Element.InvokeAction (a,b,c);
}
}
}