採用過載URL的方式實現Java與Js互動
在Android中,常用的Java與Js互動的實現方式是通過函式addJavascriptInterface進行新增在Js中使用的回撥代理類。
這種方法雖然方便,但是寫出來的js程式碼並不通用。如果IOS也要實現類似的功能或業務,則IOS要另外寫一套Js程式碼。所以不太推薦。
推薦使用過載URL的方式來實現,因為基本所有的平臺都擁有在載入某個URL之前進行一些處理的回撥函式。所以這種方式會更加的通用。
響應Javascript中的alert
在Android的WebView控制元件中,預設對JS的alert函式是沒有任何反應的
要想彈出對應的對話方塊,則需要我們自己進行實現
具體實現程式碼如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
webView.getSettings().setJavaScriptEnabled(true); webView.setWebChromeClient(new WebChromeClient(){ @Override public boolean onJsAlert(WebView view, String url, String message, final JsResult result) { AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setTitle("測試alert"); builder.setMessage(message); builder.setPositiveButton("確定", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { result.confirm(); } }); builder.show(); return true; } }); |
通過以上程式碼就可以實現當JS中執行alert時,在Android上以原生的對話方塊顯示出來,當然這裡也可以直接Toast。
而這段程式碼中需要注意的地方有兩點:
1. 返回值必須為true
。
返回true,則說明已經處理了,不需要交由WebChromeClient來執行。而如果返回的是false,則Webview會繼續執行後續的js程式碼,現象就是,彈出對話方塊之後,使用者還沒點確定,後續的js程式碼已經執行完了.
- 最後必須呼叫result.confirm()。
原因在於,如果沒有呼叫此函式,則後續的JS程式碼將無法繼續執行下去。最常見的現象就是,alert對話方塊只出現一次,第二次再進行alert的時候沒有任何反應。其實這裡是因為沒有呼叫confirm函式,就相當於在瀏覽器中alert之後,使用者沒有點確定。 - result.confirm()應該放到onClick回撥中。
正如前面說的,呼叫confirm函式,就相當於使用者點選了確定按鈕。因此,我們要把confirm函式的呼叫放到Android原生對話方塊的“確定”按鈕的回撥函式中進行呼叫。 之前沒理解透,把confirm函式放在了builder.show之後進行呼叫,結果現象是alert之後,對話方塊彈出來了,但是後續的js程式碼沒有阻塞,而是繼續執行下去了,變得就像是非同步了一樣,和在chrome中呼叫js程式碼的執行邏輯不一致。
不過,如果需求就是要直接執行下去,那也可以,只要理解了就行。
訪問證照有問題的SSL網頁
對於有證照問題的網頁,比如過期、資訊不正確、發行機關不被信任等,Webview預設情況下會拒絕訪問。而PC端瀏覽器的處理則是提供使用者進行選擇是否要繼續,在android也是可以實現的。
首先第一種是直接繼續,不需要讓使用者進行選擇
1 2 3 4 5 6 |
@Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { // 預設為呼叫handler.cancel()方法,因此不要呼叫super的onReceivedSslError方法 // super.onReceivedSslError(view, handler, error); handler.proceed(); } |
這裡要注意的是,千萬不要呼叫super的onReceivedSslError方法,因為此方法中已經呼叫了handler.cancel()。
如果呼叫了,則會出現第一次無法載入,第二次卻能正常訪問的現象。
慎重在shouldoverrideurlloading中返回true
當設定了WebviewClient時,在shouldoverrideurlloading中如果不需要對url進行攔截做處理,而是簡單的繼續載入此網址。
則建議採用返回false的方式而不是loadUrl的方式進行載入網址。
為什麼這麼建議呢?
因為如果採用loadUrl的方式進行載入,那麼對於載入有跳轉的網址時,進行webview.goBack就會特別麻煩。
例如載入連結如下:
A->(B->C->D)->E 括號內為跳轉
如果採用return false的方式,那麼在goBack的時候,可以從第二步直接回到A網頁。從E回到A只需要執行兩次goBack
而如果採用的是loadUrl,則沒辦法直接從第二步回到A網頁。因為loadUrl把第二步的每個跳轉都認為是一個新的網頁載入,因此從E回到A需要執行四次goBack
只有當不需要載入網址而是攔截做其他處理,如攔截tel:xxx等特殊url做撥號處理的時候,才應該返回true。