• Xamarin.Form中WebView调用JS代码和JS代码调用客户端程序


        由于在项目中使用了WebView容器来加载网页对某些信息进行编辑处理,中间需要用到拍照/图片库上传图片,在iOS中网页代码可以正常调用拍照功能和选择图库图片功能,但是在Android下面怎么都调不到拍照功能,百度了下在原生程序下面也是同样的调用不到,要自己去处理,有几种处理办法,我这里选择了用JS调用原生代码来实现拍照和图片选择功能。在Xamarin.Forms下面我们要自己写Renderer来实现。这里同样是参考Xamarin官网的例子来实现的,下面是个小例子来理解原生代码和JS代码之间的互相调用。

    1.在Form中定义HybridWebView,继承于WebView,代码如下:

      1     public class HybridWebView:WebView
      2     {
      3         public event EventHandler<EventArgs> CallAction;
      4         public void SendClick(string data)
      5         {
      6             CallAction?.Invoke(this,new EventArgs());
      7         }
      8     }

    2.在Android项目下面自定义Renderer:

      1     public class HybridWebViewRenderer:WebViewRenderer
      2     {
      3         const string JavaScriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";
      4 
      5         public HybridWebView webView;
      6 
      7         protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
      8         {
      9             base.OnElementChanged(e);
     10             if (e.OldElement != null)
     11             {
     12                 Control.RemoveJavascriptInterface("jsBridge");
     13             }
     14             if (e.NewElement != null)
     15             {
     16                 webView = e.NewElement as HybridWebView;
     17 
     18                 Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
     19                 InjectJS(JavaScriptFunction);
     20             }
     21 
     22             void InjectJS(string script)
     23             {
     24                 if (Control != null)
     25                 {
     26                     Control.LoadUrl(string.Format("javascript: {0}", script));
     27                 }
     28             }
     29         }
     30     }

    3.定义jsbridge

      1     public class JSBridge : Java.Lang.Object
      2     {
      3         readonly WeakReference<HybridWebViewRenderer> hybridWebViewRenderer;
      4 
      5         public JSBridge(HybridWebViewRenderer hybridRenderer)
      6         {
      7             hybridWebViewRenderer = new WeakReference<HybridWebViewRenderer>(hybridRenderer);
      8         }
      9 
     10         [JavascriptInterface]
     11         [Export("invokeAction")]
     12         public void InvokeAction(string data)
     13         {
     14             HybridWebViewRenderer hybridRenderer;
     15 
     16             if (hybridWebViewRenderer != null && hybridWebViewRenderer.TryGetTarget(out hybridRenderer))
     17             {
     18                 hybridRenderer.webView.SendClick(data);
     19             }
     20         }
     21     }

    4.要注意的是我们要在Android项目中引入程序集Mono.Android.Export,不然程序会报错。

    5.定义html文件中的js代码:

      1 <html>
      2 <head />
      3 <body>
      4     <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
      5     <h1>HybridWebView Test</h1>
      6     <br />
      7     Enter name: <input type="text" id="name">
      8     <br />
      9     <br />
     10     <button type="button" onclick="javascript:invokeCSCode($('#name').val());">Invoke C# Code</button>
     11     <br />
     12     <p id="result">Result:</p>
     13 
     14     <script type="text/javascript">
     15         //调用C#代码
     16         function invokeCSCode(data) {
     17             invokeCSharpAction(data);
     18         }
     19 
     20         //C#调用此js方法
     21         function print(url) {
     22             alert(url);
     23         }
     24     </script>
     25 </body>
     26 </html>
     27 

    6.在程序中调用

      1 public MainPage()
      2 		{
      3 			InitializeComponent();
      4 		    webView.Source = string.Format("file:///android_asset/Content/{0}", "index.html");
      5             webView.CallAction += WebView_CallAction;
      6         }
      7 
      8         private void WebView_CallAction(object sender, EventArgs e)
      9         {
     10             object test = "http://www.baidu.com";
     11             webView.Eval(string.Format("print('" + test + "')"));
     12         }

     代码地址:https://github.com/zjmsky/HybridWebViewTest

  • 相关阅读:
    【每天一道PAT】1001 A+B Format
    C++ STL总结
    开篇
    happen-before原则
    java多线程的状态转换以及基本操作
    集合初始容量
    fail-fast机制
    Stack
    Iterator
    Vector
  • 原文地址:https://www.cnblogs.com/zjmsky/p/7247683.html
Copyright © 2020-2023  润新知