天天看點

WebView的使用總結WebView的常見用法

WebView是android常見的一個元件,随着混合開發的發展,越來越多的公司使用原生和h5共同開發。是以使用WebView的頻率越來越高了,是以想做次總結

WebView的常見用法

最簡單的用法

loadUrl

loadUrl(String url);
           

加載一個網頁,其中注意的是

1. 需要加入聯網權限,

2. 還有網址必須完整即以http://或者ftp://等協定開頭,不能省略!不然将加載不出來,

3. assert中的html檔案。字首換成file:///android_asset/

4. 加載sd卡中的html檔案,字首換成content://

loadData

public void loadData(String data, String mimeType, String encoding)
           

加載代碼塊。其中對于data可以采用encode一下再加載,速度快點

loadDataWithBaseURL

public void loadDataWithBaseURL(String baseUrl, String data,String mimeType, String encoding, String historyUrl)
           

相對于loadData,其實就是一個相對路徑和絕對路徑的問題,loadData要求必須是絕對路徑,而loadDataWithBaseURL則可以是相對路徑。historyUrl可以為null。

WebSettings的常見配置

如果我們需要設定WebView的屬性,是通過WebView.getSettings()擷取取設定WebView的WebSettings對象,然後調用WebSettings中的方法來實作的配置一些屬性,來幫我們實作一些常見的基本操作。比如字型大小,支援縮放等

//---------------------------------------------------
// 縮放
// 1 設定支援縮放,預設true
setSupportZoom(boolean support)

// 2 設定顯示縮放的元件 預設true
setDisplayZoomControls(boolean enabled)  

// 3 設定是否使用縮放的内置元件  預設false
setBuiltInZoomControls(boolean enabled) 
//--------------------------------------------------


//--------------------------------------------------
// 1 設定media 手勢播放media
setMediaPlaybackRequiresUserGesture(boolean require)
//--------------------------------------------------

//--------------------------------------------------
//寬度
// 1 設定概述模式浏覽界面,當頁面寬度超過WebView顯示寬度時,縮小頁面适應WebView。預設false 
setLoadWithOverviewMode(boolean overview)    

// 2 設定支援ViewPort的meta tag屬性,如果頁面有ViewPort meta tag 指定的寬度,則使用meta tag指定的值,否則預設使用寬屏的視圖視窗 
setUseWideViewPort(boolean use)  
//--------------------------------------------------

//--------------------------------------------------
// 字型和大小
// 1 設定頁面文字縮放百分比,預設100% 
setTextZoom(int textZoom)  

// 2 設定最小字型,預設8. 取值區間[1-72],超過範圍,使用其上限值。 
setMinimumFontSize(int size)

//3 設定最小邏輯字型,預設8. 取值區間[1-72],超過範圍,使用其上限值。 
setMinimumLogicalFontSize(int size)  

//4 設定預設字型大小,預設16,取值區間[1-72],超過範圍,使用其上限值。 
setDefaultFontSize(int size)

//5 設定預設填充字型大小,預設16,取值區間[1-72],超過範圍,使用其上限值
setDefaultFixedFontSize(int size)  

//6 設定預設字型大小 SMALLEST is 50% SMALLER is 75% NORMAL is 100% LARGER is 150% LARGEST is 200%
setTextSize(WebSettings.TextSize t)

//7 設定标準的字型族,預設”sans-serif”。
setStandardFontFamily(String font) 

//8 設定混合字型族。預設”monospace”
setFixedFontFamily(String font) 

//9 設定SansSerif字型族。預設”sans-serif”
setSansSerifFontFamily(String font)

//10 設定SerifFont字型族,預設”sans-serif” 
setSerifFontFamily(String font) 

//11 設定CursiveFont字型族,預設”cursive” 
setCursiveFontFamily(String font)  

//12 設定FantasyFont字型族,預設”fantasy” 
setFantasyFontFamily(String font)  

//13 設定頁面的編碼格式,預設UTF-8
setDefaultTextEncodingName(String encoding)
//--------------------------------------------------------

//--------------------------------------------------------
//加載圖檔
//1 設定是否加載圖檔資源 包括嵌入的本地圖檔資源和網絡圖檔。 預設true 
setLoadsImagesAutomatically(boolean flag)  

//2 是否加載網絡圖檔資源 預設true
setBlockNetworkImage(boolean flag) 

//3 設定是否加載網絡資源。注意如果值從true切換為false後,WebView不會自動加載,除非調用WebView#reload()
setBlockNetworkLoads(boolean flag) 
//-------------------------------------------------------

//--------------------------------------------------------
//通路
//1 設定允許通路WebView内部檔案,預設true 
setAllowFileAccess(boolean allow)  

//2 設定允許擷取WebView的内容URL ,可以讓WebView通路ContentPrivider存儲的内容。 預設true
setAllowContentAccess(boolean allow) 

//3 設定加載不安全資源的WebView加載行為,MIXED_CONTENT_ALWAYS_ALLOW和MIXED_CONTENT_NEVER_ALLOW 
setMixedContentMode(int mode)  
//--------------------------------------------------------

//緩存
//1 是否儲存表單資料,預設false 
//setSaveFormData(boolean save) 

//2 是否允許資料庫存儲
setDatabaseEnabled(boolean flag)

//3 設定存儲定位資料庫的位置,考慮到位置權限和持久化Cache緩存
setGeolocationDatabasePath(String databasePath) 

//4 是否允許Cache,預設false
setAppCacheEnabled(boolean flag)

//5 設定Cache API緩存路徑。
setAppCachePath(String appCachePath)

//6 是否存儲頁面DOM結構,預設false
setDomStorageEnabled(boolean flag) 

//7 基于WebView導航的類型使用緩存 LOAD_DEFAULT 預設加載方式 LOAD_CACHE_ELSE_NETWORK 按網絡情況使用緩存 LOAD_NO_CACHE 不使用緩存 LOAD_CACHE_ONLY 隻使用緩存 
setCacheMode(int mode) 

//--------------------------------------------------------

//--------------------------------------------------------
//js
//1 設定是否允許執行JS
setJavaScriptEnabled(boolean flag)  

//2 是否允許Js通路任何來源的内容。包括通路file scheme的URLs
setAllowUniversalAccessFromFileURLs(boolean flag)

//3 是否允許Js通路其他file scheme的URLs
setAllowFileAccessFromFileURLs(boolean flag)  

//4 是否允許JS自動打開視窗。預設false 
setJavaScriptCanOpenWindowsAutomatically(boolean flag)
//--------------------------------------------------------

// ------------------------------------------------------
// 其它
//1 設定WebView代理,預設使用預設值
setUserAgentString(String ua) 

//是否允許定位,預設true
setGeolocationEnabled(boolean flag)

//是否支援多視窗,如果設定為true 
setSupportMultipleWindows(boolean support)
           

JS和本地的互調

JS調用Android

主要代碼:

mWebView = (WebView) findViewById(R.id.webview);  

WebSettings webSettings = mWebView.getSettings();  
webSettings.setJavaScriptEnabled(true);  
mWebView.addJavascriptInterface(mJavaInterface, "rrtoyewx");
           

其中

public void addJavascriptInterface(Object obj, String interfaceName)
           

第一個參數obj對象中實作JS調用android的實作的方法,第二個參數interfaceName是向WebView注入一個interfaceName的對象,這個對象綁定的是obj對象,即js的中調用方法的對象。

舉個例子

js調用android的sendMessage的方法,并傳遞一個String的參數。

js代碼

<html lang="en">  
    <head>  
        <meta charset="UTF-8">  
        <title>Title</title>  
        <h1>你好</h1>  
        <input type="button" value="js調native" onclick="ok()">  
    </head>  
    <body>  
        <script type="text/javascript">  
        function ok() {  
            rrtoyewx.sendMessage("我調用了android的中代碼");  
        }  
        </script>  
    </body>  
</html>  
           

android的代碼

mWebView = (WebView) findViewById(R.id.webview);  

WebSettings webSettings = mWebView.getSettings();  
webSettings.setJavaScriptEnabled(true);  
mWebView.addJavascriptInterface(mJavaInterface, "rrtoyewx");
           

JavaInterface的代碼

public class JavaInterface{
    @JavascriptInterface 
    public void sendMessage(String message){
        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); 
    }
}
           

其中js調用java的代碼會造成Android WebView的Js對象注入漏洞,會造成一些安全性的問題,關于這個的解決方法就是也有别人分析出并解決了

Android WebView的Js對象注入漏洞解決方案,其中對4.2以上采用@JavascriptInterface的注釋,而對于4.2以下的系統

1. 不使用addJavascriptInterface的方法。

2. 在WebChromeClient的方法中的回調方法中,去解析相應的參數,方法名,然後通過反射去相應本地方法。

3. 如果存在傳回值,則通過的load的方式,會調用的相應的方法。

Android 調用js的方法

loadUrl();
           

直接通過loadUrl()的方式去加載js的方法。

舉個例子

Android 調用js的alert的方法

Js

<html lang="en">  
    <head>  
        <meta charset="UTF-8">  
        <title>Title</title>  
        <h1 id="h">Rrtoyewx</h1>  
        <input type="button" value="js調native" onclick="ok()">  
    </head>  
    <body>  
        <script type="text/javascript">  
            function showAlert(i)  
            {  
                ....
            }  
        </script>  
    </body>  
</html> 
           

Android 的代碼

如果js的方法存在傳回值,一種方式需要用js調用java的方式将傳回值作為傳回。而4.4之後,還有另一種方式,通過evaluateJavascript的方法去調用js的方法,并在valueCallBack的回調方法“onReceiveValue(String value)”的方法回調。

public void evaluateJavascript("methodName",valueCallBack)
           
mWebView.evaluateJavascript("getGreetings()", new ValueCallback() {  
       @Override  
       public void onReceiveValue(String value) {  
           Log.d("Rrtoyewx", value);  
       }  
   }); 
           

注意,回調方法在主線程,第二,傳回值隻接受string的

WebViewClient的回調方法

onPageStarted

public void onPageStarted(WebView view, String url, Bitmap favicon)   
           

目前頁面開始加載時調用,我們可以在其中做一些準備的工作,比如加載processbar

onPageFinished

public void onPageFinished(WebView view, String url)  
           

目前頁面的加載完成時調用,我們可以在其中釋放一個資源,和關閉一些東西

shouldOverrideUrlLoading

public boolean shouldOverrideUrlLoading(WebView view, String url)
           

函數會在加載其他的連結時回調,表示webview是否屏蔽的這個連結,預設傳回false,如果傳回true則表示不會加載這個url了。我們可以在其中屏蔽一些操作。

onReceivedError

public void onReceivedError(WebView view, int errorCode,String description, String failingUrl)  
           

參數的說明:WebView view:目前的WebView執行個體,int errorCode:錯誤碼,String description:錯誤描述,String failingUrl:目前出錯的URL。一般加載本地的404界面的,即出現一個錯誤提示。

onReceivedSslError

public void onReceivedSslError(WebView view, SslErrorHandler handler,SslError error) 
           

HTTPS協定是通過SSL來通信的,是以當使用HTTPS通信的網址(以https://開頭的網站)出現錯誤時,就會回調的該方法,參數說明

WebView view:目前的WebView執行個體,SslErrorHandler handler:SslErrorHandler.proceed()和SslErrorHandler.cancel(),SslErrorHandler.proceed()表示忽略錯誤繼續加載,SslErrorHandler.cancel()表示取消加載。在onReceivedSslError的預設實作中是使用的SslErrorHandler.cancel()來取消加載。SslError error:目前的的錯誤對象,SslError包含了目前SSL錯誤的基本所有資訊。

注意

1 onReceivedSslError回調,不一定會回調onReceivedError的方法。

2 加載預設的onReceivedSslError的會出現的白屏。

3 可以忽略這個錯誤繼續加載的

shouldInterceptRequest

public WebResourceResponse shouldInterceptRequest(WebView view,  
        String url) ;
           

當頁面中許多的資源檔案,每請求一個資源檔案,都會回調這個方法,這個不主線程調用。是以我們可以在請求資源的時候,在這裡屏蔽一些操作

onLoadResource

public void onLoadResource(WebView view, String url
           

請求資源檔案的時候調用,

onScaleChanged

public void onScaleChanged(WebView view, float oldScale, float newScale)  
           

webView的發生縮放改變的時候調用

shouldOverrideKeyEvent

public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event)  
           

屏蔽一個按鍵的操作,傳回false,則不屏蔽,交給webview處理,true反之

onFormResubmission

onFormResubmission(WebView view, Message dontResend, Message resend)  
           

設定是否重發資料,post的請求的時候,預設不重新發送

doUpdateVisitedHistory

doUpdateVisitedHistory(WebView view, String url, boolean isReload) 
           

通知主機程式更新通路的連結

onUnhandledInputEvent

讓主程式處理WebView未處理的Input Event。

onReceivedLoginRequest

onReceivedLoginRequest(WebView view, String realm, String account, String args)
           

自動登入請求的回調方法

WebChromeClient的事件

onJsAlert

public boolean onJsAlert(WebView view, String url, String message,JsResult result)
           

網頁調用alert的時候調用

onJsConfirm(),傳回值代表是否消費, JsResult 的cancle的方法和con

public boolean onJsConfirm(WebView view, String url, String message,JsResult result)
           

網頁調用confirm的時候調用,傳回值代表是否消費,

onJsPrompt

public boolean onJsPrompt(WebView view, String url, String message,String defaultValue, JsPromptResult result) 
           

網頁調用prompt的時候調用,傳回值代表是否消費,

onConsoleMessage

public boolean onConsoleMessage(ConsoleMessage consoleMessage)
           

列印console的消息的時候,常用來監視js代碼的錯誤

onProgressChanged

public void onProgressChanged(WebView view, int newProgress)
           

加載頁面的進度的改變的時候,

onReceivedTitle

public void onReceivedTitle(WebView view, String title)
           

頁面的title的發生變化時候的回調

onReceivedIcon

public void onReceivedIcon(WebView view, Bitmap icon)
           

接受到新的icon的回調方法

onReceivedTouchIconUrl

public void  onReceivedTouchIconUrl(WebView view, String url, boolean precomposed)
           

頁面的按下圖示的icon的url

getVisitedHistory

public void getVisitedHistory(ValueCallback callback)
           

擷取通路頁面的通路曆史

onShowFileChooser

public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback,FileChooserParams fileChooserParams)
           

試圖打開檔案的浏覽器的回調方法,其中fileChooserParams對象包含的許多的資訊。比如打開檔案的mimeType,mode等