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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM