Android WebView 與 JavaScript 互動 November 21, 2015 https://mthli.github.io/Android-WebView-JavaScript
最近在做一些和 WebView 相關的工作,期間涉及到與 JavaScript 互動的操作,網搜了很多部落格,感覺寫得都不算很好,花了比較多的時間才看明白。在這裡重新歸納總結一下,希望對大家有所協助。 操作前提
因為我們的目標是與 JavaScript 進行互動,因此webView.getSettings().setJavaScriptEnabled(true); 當然是必須的。 通過 WebView 調用 JavaScript 方法
如果只是單純地想要調用 JavaScript 的方法,可以直接使用webView.loadUrl("javascript:METHOD") 來實現,METHOD 就是你期望的 JavaScript 方法,相當於直接在 Chrome 中按 F12 進入 Console 操作。
需要注意的是,調用 loadUrl() 在 4.4 之前的 WebView 中,會導致網頁重載(4.4 之後現象無明顯影響),而網頁重載會導致軟鍵盤輸入焦點消失等問題。 向 JavaScript 中傳遞參數
首先我們需要注意的一件事是,JavaScript 是弱類型的,所以對於從 Java 中傳遞的參數,我們需要自己在 JavaScript 中處理,而不能想當然的傳進去就用。
對於字串形式的參數,一定要記住使用單引號 ' 將其包裹,否則 JavaScript(可能)會無法解析這個字串,提示未定義。
除此意外還要注意一個坑,假設我們希望向 JavaScript 中傳遞字串中包含\ 或者 %5C 的子串,那麼都會導致在 JavaScript 中的轉義,因此我們需要對 \ 或 %5C 進行處理。比如對於 \ 我們就可以做一個字串替換,變為 \\ ,而 \\ 會被轉義為我們真正需要的 \ 。
剩下的事情就很簡單啦,比如 JavaScript 中有這麼一個方法:
// 插入一段 HTMLfunction insertHTML(html) { ...}
在 WebView 中我們就可以這麼調用:
String html = ...;html = html.replaceAll("\\\\", "\\\\\\\\");webView.loadUrl("javascript:insertHTML('" + html + "')");
JavaScript 調用 Java 方法
想要在 JavaScript 中調用相關的 Java 方法,就需要對 WebView 做一些設定了。
首先我們需要在 WebView 中添加 JavaScript 可以直接調用的介面,為了方便起見我就直接將整個 WebView 作為介面對象傳遞到addJavascriptInterface() 中,同時記住給介面對象起一個名字;
接著我們要給所有 JavaScript 可以調用的 Java 方法添加@JavascriptInterface 的註解;
然後就可以在你的 JavaScript 代碼裡調用 Java 方法啦。整體代碼看起來大概是這樣的:
public class MyWebView extends WebView { public MyWebView(Context context) { ... getSettings().setJavaScriptEnabled(true); addJavascriptInterface(this, "MyName"); ... } @JavascriptInterface public void example() { ... }}
在 JavaScript 中這樣寫:
// 調用 MyWebView 中的 example() 方法function example() { MyName.example();}
擷取 JavaScript 的傳回值
很多時候我們使用 JavaScript 不止是執行一個方法,而是希望得到一個傳回值,比如一個布爾值,或者一個字串。
在 Android 4.4 及其以上版本中, Google 在 WebView 中提供了一個叫做evaluateJavascript() 的方法,當你期望的 JavaScript 方法執行完畢時,會產生一個回調,傳回傳回值的字串形式,因此你需要自己手動轉換為所需的類型。具體的樣本可以參考這個連結。
當然我們也可以使用簡單並且相容低版本 Android 的方法來實現。比如我們在 MyWebView 中有這麼一個方法:
@JavascriptInterfacepublic void log(String tag, boolean value) { Log.v(tag, String.valueOf(value));}
在 JavaScript 中這樣寫:
function log() { MyName.log("tag", true);}
JavaBridge 會自動將參數轉換為所需的類型,當然前提是你要保證轉換一定正確。 關於 UI 層面的修改
Android 只允許在主線程中修改 UI 。如果你在 JavaScript 中調用了 WebView 的方法來修改介面,由於 JavaBridge 並不在主線程中,我們要建立一個位於主線程的 Handler 來操作 UI 。
public class MyWebView extends WebView { private Handler handler = new Handler(Looper.getMainLooper()); ... @JavascriptInterface public void changeUI() { handler.post(new Runnable() { ... }); }}
Chrome 遠端偵錯
如果你使用的是 Android 4.4 及其以上版本的 WebView ,那麼這將是一個非常有用的功能,具體可以參考這個連結。
如果你對上述文章還有什麼不明白的地方,可以參考 Google 的官方文檔。 返回