Laut Dokumentation soll es möglich sein, in einem Android WebView von JavaScript aus auf Java-Funktionen zuzugreifen. Entsprechend sollte dies auch mit C# und Xamarin möglich sein. Viel Nachforschen und Ausprobieren – leider war kein Online-Beispiel wirklich funktionsfähig – führten mich schließlich zu folgender Lösung (für API Level 19):
var webView = FindViewById(Resource.Id.webView); webView.Settings.JavaScriptEnabled = true; var webChromeClient = new MyWebChromeClient(); webView.SetWebChromeClient(webChromeClient); var webViewClient = new MyWebViewClient(); webView.SetWebViewClient(webViewClient); webView.AddJavascriptInterface(webViewClient, "apiCalls"); webView.LoadUrl(...);
Dabei scheint hier vor allem der eigene WebChromeClient wichtig zu sein. Das eigentliche Interface implementiert die veröffentlichten Methoden „public“ und mit „Export“ und „JavascriptInterace“ getaggt wie folgt:
[Export("setNextCallDetails")] [JavascriptInterface] public void SetNextCallDetails(string method, string jsonData) { ... }
In JavaScript wird dies dann so aufgerufen:
<script src="js/vendor/jquery-2.1.3.min.js"></script> <script> $(document).ajaxSend(function (event, jqXHR, ajaxOptions) { if (apiCalls) { if (apiCalls.setNextCallDetails) { var method = ajaxOptions.type; var jsonData = (typeof ajaxOptions.data === "string" ? ajaxOptions.data : ajaxOptions.data ? JSON.stringify(ajaxOptions.data) : null); apiCalls.setNextCallDetails(method, jsonData); } } }); </script>
Wozu das Ganze?
Ganz einfach: der WebView unterstützt (auf API Level 19) keine Übermittlung der HTTP-Methode und des POST/PUT-Bodys an den registrierten WebViewClient. Mit obiger Methode kann ich AJAX-Aufrufe abfangen, die nötigen Informationen vorab setzen und dann den WebViewClient seine Arbeit tun lassen.