- 重點1:loadUrl及loadDataWithBaseURL的使用
這部分內容已經在 UI組件——WebView部分api釋義 講過了,還不懂得可以去看一下
- 重點2:h5頁面在Android WebView中的適配問題
筆者踩過的坑是h5頁面未對移動端做任何適配,而且在h5頁面指定了,導致Android端適配很差,我們Android端在這裏自己搞各種適配的工作,結果還是不理想,其實這個問題理想解決方法是:h5頁面要儘量使用百分比佈局,比如指定width:100%,那麼就能解決多數問題,但是還有一類問題無法解決,h5頁面中的有些文本在移動端顯示的特別小,如果想要正常顯示,那麼在h5的中添加 name=”viewport” content=”width=device-width”來解決;具體爲
- 重點3:對加載網頁時出現的失敗網頁的處理
通常情況下,WebView加載網頁如果出現錯誤,那麼錯誤提示便是網頁本身的錯誤提示,這對用戶來說很不友好,因此,爲了給客戶良好的體驗感,我們會把原生的錯誤提示頁面替換爲一個比較友好的提示頁面,具體是什麼頁面可以找設計。要替換原生的錯誤頁面,我們就要知道當頁面發生錯誤時會回調什麼方法,然後我們在那裏做攔截處理,便可以成功替換頁面了。當加載錯誤時會回調onReceivedError(WebView view, WebResourceRequest request, WebResourceError error)和onReceivedHttpError( WebView view, WebResourceRequest request, WebResourceResponse errorResponse),因此我們在這裏做替換就可以了。注意,第一個方法要求api 23,要做一些適配工作,比如,我們可以判斷版本>23時用第一個方法,其他情況下用這個方法:onReceivedError(WebView view, int errorCode,String description, String failingUrl)。
- 重點4:與js交互
這是WebView的重中之重,分兩個方向講1:Android調用js,2:js調用Android
- 1:Android調用js
android 調用js又分爲兩種情況,一種是無返回值的調用,一種是有返回值的調用。無論哪種情況都需要添加webSettings.setJavaScriptEnabled(true);否則不會生效
- a:無返回值的交互
Android調用js無需返回值時直接使用:webview.loadUrl(str);str是需要執行的js語句,UI組件——WebView部分api釋義 這裏已經講過了。 - b:有返回值的調用
Android調用js有返回值的方法是在Android4.4(api 19)以後新增的方法:evaluateJavascript(String script, ValueCallback resultCallback);script是即將執行的js語句,resultCallback是執行結果的回調
- a:無返回值的交互
- 2:js調用Android
首先:Android需要提供可調用的方法,這裏以獲取html的寬度爲例:
- 1:Android調用js
//通過與js交互來獲取HTML的寬度
class JavaScriptToAndroid {
@JavascriptInterface//必須要記得加上
public void getWidth(String value) {
if (value != null) {
int width = Integer.parseInt(value);
Toast.makeText(WebViewActivity.this, "width of html is: " + width + "px", Toast.LENGTH_SHORT).show();
}
}
}
然後設置
settings.setJavaScriptEnabled(true);
並將該類注入到js中,並以Android作爲調用的標識
webView.addJavascriptInterface(new JavaScriptToAndroid(), "Android");
最後在html中調用這個方法,html代碼:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin:0;
padding:0;
}
.box{
width: 100%;
height:500px;
background: pink;
margin:0 auto;
}
</style>
</head>
<body>
<div class="box">
<p>
<input type="button" id="enter" value="調用Android" onclick="testClick();"/>
</p>
</div>
</body>
<script>
function testClick(){
window.Android.getWidth(document.getElementsByClassName("box")[0].offsetWidth)
}
</script>
</html>
至此,交互結束
重點5:埋下的坑
- 坑1:安全問題
webView 在api 4.0 到4.2 之間增加了 searchBoxJavaBridge_ 方法,導致webView 存在安全漏洞解決方法是:在4.2 以前的版本不用 addJavascriptInterface 接口,並且在4.0-4.2之間移除searchBoxJavaBridge方法 —>我也是google來的,並未遇到
public class MyWebView extends WebView{ public MyWebView(Context context) { super(context); removeSearchBoxJavaBridgeInterface(); } public MyWebView(Context context, AttributeSet attrs) { super(context, attrs); removeSearchBoxJavaBridgeInterface(); } public MyWebView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); removeSearchBoxJavaBridgeInterface(); } public MyWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); removeSearchBoxJavaBridgeInterface(); } private void removeSearchBoxJavaBridgeInterface() { if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17) { removeJavascriptInterface("searchBoxJavaBridge_"); } } @Override public void addJavascriptInterface(Object object, String name) { if (Build.VERSION.SDK_INT >= 17) { super.addJavascriptInterface(object, name); } } }
- 坑2:內存泄漏問題
@Override protected void onDestroy() { super.onDestroy(); if (mMyWebView != null) { mMyWebView.stopLoading(); mMyWebView.getSettings().setJavaScriptEnabled(false); ViewGroup parent = (ViewGroup) mMyWebView.getParent(); parent.removeAllViews();//ViewGroup中的方法 try { mMyWebView.destroy();//銷燬WebView } catch (Exception e) { e.printStackTrace(); } } }
- 坑3:執行js腳本偶發性失敗(尚未解決)
- 坑1:安全問題