繁体   English   中英

Xamarin HybridWebView 从 C# 调用 JS 函数

[英]Xamarin HybridWebView calling JS function from C#

我正在尝试获得一个 HybridWebView,其中 JS 和 C# 代码可以相互通信。 我遵循了官方文档,从 JS 调用 C# 代码工作正常。 但是我也需要另一种方式,这在提到的教程中没有指导。 这是我有多远:

在我的 HybridWebView 控件中,我添加了以下几行:

public event EventHandler CallJavascript;

public void InvokeJS()
{
    if(CallJavascript != null)
    {
        CallJavascript(this, EventArgs.Empty);
    }
}

在我的自定义渲染器中,我在OnElementChanged()方法中添加了 CallJavascript 方法和它

protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
    {
        base.OnElementChanged(e);

        if (Control == null)
        {
            var webView = new Android.Webkit.WebView(_context);
            webView.Settings.JavaScriptEnabled = true;
            webView.SetWebViewClient(new JavascriptWebViewClient($"javascript: {JavascriptFunction}"));
            SetNativeControl(webView);


        }
        if (e.OldElement != null)
        {
            Control.RemoveJavascriptInterface("jsBridge");
            var hybridWebView = e.OldElement as HybridWebView;
            hybridWebView.Cleanup();

            e.OldElement.CallJavascript += OnElementCallJavascript;
        }
        if (e.NewElement != null)
        {
            Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
            Control.LoadUrl($"file:///android_asset/Content/{Element.Uri}");
            e.NewElement.CallJavascript += OnElementCallJavascript;
        }
    }


private void OnElementCallJavascript(object sender, EventArgs e)
{
    var webView = new Android.Webkit.WebView(_context);
    Device.BeginInvokeOnMainThread(() =>
    {
        webView.EvaluateJavascript("javascript:increaseCount();", null);
    });
}

但是,我在 OnElementCallJavascript 中获得的 webview 不是我从中调用方法的 webview,因此没有评估 javascript。 任何人都知道我如何实现这一目标?

问题是我正在创建一个新的Android.WebKit.WebView 像这样使用它解决了问题:

Device.BeginInvokeOnMainThread(() =>
{
     Control.EvaluateJavascript("javascript:increaseCount();", null);
});

直接/直接使用这样的东西怎么样?

e.NewElement.CallJavascript  += (sender, args) =>
{                    
    Control.EvaluateJavascript("javascript:increaseCount();", null);
};

在 Xamarin.Forms 中的 HybridWebView 中定义可绑定布局和操作:

 public class HybridWebView : WebView
{
    Action<string> action;
    public static BindableProperty EvaluateJavascriptProperty =
    BindableProperty.Create(nameof(EvaluateJavascript), typeof(Func<string, Task<string>>), typeof(HybridWebView), null, BindingMode.OneWayToSource);

    public Func<string, Task<string>> EvaluateJavascript
    {
        get { return (Func<string, Task<string>>)GetValue(EvaluateJavascriptProperty); }
        set { SetValue(EvaluateJavascriptProperty, value); }
    }

    public void RegisterAction(Action<string> callback)
    {
        action = callback;
    }

    public void Cleanup()
    {
        action = null;
    }

    public void InvokeAction(string key)
    {
        if (action == null)
        {
            return;
        }
        action.Invoke(key);
    }
}

在您的页面中调用 EvaluateJavacript:

await webview.EvaluateJavascript("javascript:increaseCount();");

在您的渲染器中:

private HybridWebView xfWebView;
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
    {
        base.OnElementChanged(e);

        if (Control == null)
        {
            var webView = new Android.Webkit.WebView(_context);
            webView.Settings.JavaScriptEnabled = true;
            webView.SetWebViewClient(new JavascriptWebViewClient($"javascript: {JavascriptFunction}"));
            SetNativeControl(webView);


        }
        if (e.OldElement != null)
        {
            Control.RemoveJavascriptInterface("jsBridge");
            var hybridWebView = e.OldElement as HybridWebView;
            hybridWebView.Cleanup();

            e.OldElement.CallJavascript += OnElementCallJavascript;
        }
        if (e.NewElement != null)
        {
            xfWebView = e.NewElement;
            Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
            if (xfWebView != null)
                {
                    xfWebView.EvaluateJavascript = async (js) =>
                    {
                        var reset = new ManualResetEvent(false);
                        var response = string.Empty;
                        Device.BeginInvokeOnMainThread(() =>
                        {
                            Control?.EvaluateJavascript(js, new JavascriptCallback((r) => { response = r; reset.Set(); }));
                        });
                        await Task.Run(() => { reset.WaitOne(); });
                        return response;
                    };
                }
         Control.LoadUrl($"file:///android_asset/Content/{Element.Uri}");
        }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM