Android WebView 開發詳解(二)
轉載請註明出處 http://blog.csdn.net/typename/article/details/39495409 powered by meichal zhao
概覽:
Android WebView 做為承載網頁的載體控制項,他在網頁顯示的過程中會產生一些事件,並回調給我們的應用程式,以便我們在網頁載入過程中做應用程式想處理的事情。比如說用戶端需要顯示網頁載入的進度、網頁載入發生錯誤等等事件。 WebView提供兩個事件回調類給應用程式層,分別為WebViewClient,WebChromeClient開發人員可以繼承這兩個類,接手相應事件處理。WebViewClient 主要提供網頁載入各個階段的通知,比如網頁開始載入onPageStarted,網頁結束載入onPageFinished等;WebChromeClient主要提供網頁載入過程中提供的資料內容,比如返回網頁的title,favicon等。
1.WebViewClient的基本使用 建立WebViewClient執行個體並設定到WebView對象中,具體代碼參考如下:
class MyAndroidWebViewClient extends WebViewClient { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { // TODO } @Override public void onPageFinished(WebView view, String url) { // TODO }
}webview.setWebViewClient(new MyAndroidWebViewClient ());
2.WebViewClient API詳解1)網頁載入時機部分
public boolean shouldOverrideUrlLoading(WebView view, String url)
當載入的網頁需要重新導向的時候就會回調這個函數告知我們應用程式是否需要接管控制網頁載入,如果應用程式接管,並且return true意味著主程式接管網頁載入,如果返回false讓webview自己處理。
參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。@param url 即將要被載入的url@return true 當前應用程式要自己處理這個url, 返回false則不處理。
Tips(1) 當請求的方式是"POST"方式時這個回調是不會通知的。(2) 當我們訪問的地址需要我們應用程式自己處理的時候,可以在這裡截獲,比如我們發現跳轉到的是一個market的連結,那麼我們可以直接跳轉到應用市場,或者其他app。
public void onPageStarted(WebView view, String url, Bitmap favicon)
當核心開始載入訪問的url時,會通知應用程式,對每個main frame這個函數只會被調用一次,頁麵包含iframe 或者framesets 不會另外調用一次onPageStarted,當網頁內內嵌的frame 發生改變時也不會調用onPageStarted。
參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。@param url 即將要被載入的url@param favicon 如果這個favicon已經儲存在本機資料庫中,則會返回這個網頁的favicon,否則返回為null。
Tips:(1) iframe 可能不少人不知道什麼含義,這裡我解釋下,iframe 我們載入的一張,下面有很多連結,我們隨便點擊一個連結是即當前host的一個iframe.(2) 有個問題可能是開發人員困惑的,onPageStarted和shouldOverrideUrlLoading 在網頁載入過程中這兩個函數到底哪個先被調用。 當我們通過loadUrl的方式重新載入一個網址時候,這時候會先調用onPageStarted再調用shouldOverrideUrlLoading,當我們在開啟的這個網址點擊一個link,這時候會先調用shouldOverrideUrlLoading 再調用onPageStarted。不過shouldOverrideUrlLoading不一定每次都被調用,只有需要的時候才會被調用。
public void onPageFinished(WebView view, String url)
當核心載入完當前頁面時會通知我們的應用程式,這個函數只有在main frame情況下才會被調用,當調用這個函數之後,渲染的圖片不會被更新,如果需要獲得新圖片的通知可以使用@link WebView.PictureListener#onNewPicture。
參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。@param url 即將要被載入的url
public void onLoadResource(WebView view, String url)
通知應用程式WebView即將載入url 制定的資源
參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。@param url 即將載入的url 資源
public WebResourceResponse shouldInterceptRequest(WebView view, String url)
通知應用程式核心即將載入url制定的資源,應用程式可以返回本地的資源提供給核心,若本地處理返回資料,核心不從網路上擷取資料。
參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。@param url raw url 制定的資源@return 返回WebResourceResponse包含資料對象,或者返回null
Tips這個回調並不一定在UI線程執行,所以我們需要注意在這裡操作View或者私人資料相關的動作。如果我們需要改變網頁的背景,或者需要實現網頁頁面顏色定製化的需求,可以在這個回調時機處理。
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
當瀏覽器訪問制定的網址發生錯誤時會通知我們應用程式,比如網路錯誤。
參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。@param errorCode 錯誤號碼可以在WebViewClient.ERROR_* 裡面找到對應的錯誤名稱。@param description 描述錯誤的資訊@param failingUrl 當前訪問失敗的url,注意並不一定是我們主url
Tips在onReceiveError我們可以自訂網頁的錯誤頁面。
public void onFormResubmission(WebView view, Message dontResend, Message resend)
如果瀏覽器需要重新發送POST請求,可以通過這個時機來處理。預設是不重新發送資料。參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。@param dontResent 當瀏覽器不需要重新發送資料時,可以使用這個參數。@param resent 當瀏覽器需要重新發送資料時, 可以使用這個參數。
public void doUpdateVisitedHistory(WebView view, String url, boolean isReload)
通知應用程式可以將當前的url儲存在資料庫中,意味著當前的訪問url已經生效並被記錄在核心當中。這個函數在網頁載入過程中只會被調用一次。注意網頁前進後退並不會回調這個函數。
參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。@param url 當前正在訪問的url @ param isReload 如果是true 這個是正在被reload的url
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error)
當網頁載入資源過程中發現SSL錯誤會調用此方法。我們應用程式必須做出響應,是取消請求handler.cancel(),還是繼續請求handler.proceed();核心的預設行為是handler.cancel();
參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。@param handler 處理使用者請求的對象。@param error SSL錯誤對象
Tips核心會記住本次選擇,如果下次還有相同的錯誤,核心會直接執行之前選擇的結果。
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)
通知應用程式WebView接收到了一個Http auth的請求,應用程式可以使用supplied 設定webview的響應請求。預設行為是cancel 本次請求。參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。@param handler 用來響應WebView請求的對象@param host 請求認證的host@param realm 認真請求所在的域
public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event)
提供應用程式同步一個處理按鍵事件的機會,菜單快速鍵需要被過濾掉。如果返回true,webview不處理該事件,如果返回false, webview會一直處理這個事件,因此在view 鏈上沒有一個父類可以響應到這個事件。預設行為是return false;參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。@param event 鍵盤事件名@return 如果返回true,應用程式處理該時間,返回false 交有webview處理。
public void onScaleChanged(WebView view, float oldScale, float newScale)
通知應用程式webview 要被scale。應用程式可以處理改事件,比如調整適配螢幕。
public void onReceivedLoginRequest(WebView view, String realm, String account, String args)
通知應用程式有個自動登入的帳號過程參數說明:@param view 請求登陸的webview@param realm 賬戶的網域名稱,用來尋找賬戶。@param account 一個可選的賬戶,如果是null 需要和本地的賬戶進行check, 如果是一個可用的賬戶,則提供登入。@param args 驗證制定參數的登入使用者
3.WebChromeClient 基本使用
4. WebChromeClient API詳解建立WebChromeClient執行個體並設定到WebView對象中,具體代碼參考如下:
public void onProgressChanged(WebView view, int newProgress)
通知應用程式當前網頁載入的進度。參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。
public void onReceivedTitle(WebView view, String title)
當document 的title變化時,會通知應用程式參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。@param title document新的titleTips這個函數調用時機不確定,有可能很早,有可能很晚,取決於網頁把title設定在什麼位置,大多數網頁一般把title設定到頁面的前面,因此很多情況會比較早回調到這個函數。
public void onReceivedIcon(WebView view, Bitmap icon)
當前頁面有個新的favicon時候,會回調這個函數。
參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。@param icon 當前頁面的favicon
public void onReceivedTouchIconUrl(WebView view, String url, boolean precomposed)
通知應用程式 apple-touch-icon的 url
參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。@param url apple-touch-icon 的服務端地址@param precomposed 如果precomposed 是true 則touch-icon是預先建立的Tips 如果應用程式需要這個icon的話, 可以通過這個url擷取得到 icon。
public void onShowCustomView(View view, CustomViewCallback callback)
通知應用程式webview需要顯示一個custom view,主要是用在視頻全屏HTML5Video support。參數說明:@param view 即將要顯示的view@param callback 當view 需要dismiss 則使用這個對象進行回調通知。
public void onHideCustomView()
退出視頻通知
public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg)
請求建立一個新的視窗,如果我們應用程式接管這個請求,必須返回true,並且建立一個新的webview來承載主視窗。如果應用程式不處理,則需要返回false,預設行為和返回false表現一樣。參數說明:@param view 請求建立新視窗的webview@param isUserGesture 如果是true,則說明是來自使用者收拾操作行為,比如使用者點選連結@param isDialog true 請求建立的新視窗必須是個dialog,而不是全屏的視窗。@param resultMsg 當webview建立時需要發送一個訊息。WebView.WebViewTransport.setWebView(WebView)Tips 具體例子如下:
private void createWindow(final Message msg) {WebView.WebViewTransport transport = (WebView.WebViewTransport) msg.obj;final Tab newTab = mWebViewController.openTab(null, Tab.this, true,true);transport.setWebView(newTab.getWebView());msg.sendToTarget(); }
public void onRequestFocus(WebView view)
webview請求得到focus,發生這個主要是當前webview不是前台狀態,是後台webview。
public void onCloseWindow(WebView window)
通知應用程式從關閉傳遞過來的webview並從view tree中remove。
public boolean onJsAlert(WebView view, String url, String message, JsResult result)
通知應用程式顯示javascript alert對話方塊,如果應用程式返回true核心認為應用程式處理這個訊息,返回false,核心自己處理。參數說明:@param view 接收WebViewClient的那個執行個體,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。
@param url 當前請求彈出javascript 對話方塊webview 載入的url地址。@param message 彈出的內容資訊@result 用來響應使用者的處理。
Tips
如果我們應用接管處理, 則必須給出result的結果,result.cancel,result.comfirm必須調用其中之後,否則核心會hang住。
public boolean onJsConfirm(WebView view, String url, String message, JsResult result)
通知應用程式提供confirm 對話方塊。參數說明同上onJsAlert
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)
通知應用程式顯示一個prompt對話方塊。 Tips必須調用result.confirm 方法如果應用程式接管這個方法。
public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result)
通知應用程式顯示一個對話方塊,讓使用者選擇是否離開當前頁面,這個回調是javascript中的onbeforeunload事件,如果用戶端返回true,核心會認為用戶端提供對話方塊。預設行為是return false。參數說明和之前介紹的onJsAlert()相同。
public void onExceededDatabaseQuota(String url, String databaseIdentifier, long quota, long estimatedDatabaseSize, long totalQuota, WebStorage.QuotaUpdater quotaUpdater)
通知應用程式webview核心web sql 資料庫超出配額,請求是否擴大資料庫磁碟配額。預設行為是不會增加資料庫配額。參數說明:
@param url 觸發這個資料庫配額的url地址@param databaseIdentifier 指示出現資料庫超過配額的標識。@param quota 未經處理資料庫配額的大小,是位元組單位bytes@param estimatedDatabaseSize 到達底線的資料大小 bytes@param totalQuota 總的資料庫配額大小 bytes@param quotaUpdater 更新資料庫配額的對象,可以使用 quotaUpdater.updateQuota(newQuota);配置新的資料庫配額大小。
public void onReachedMaxAppCacheSize(long requiredStorage, long quota, WebStorage.QuotaUpdater quotaUpdater)
通知應用程式核心已經到達最大的appcache。appcache是HTML5針對offline的一個資料處理標準。
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback)
當前頁面請求是否允許進行定位。
GeolocationPermissions.Callback的使用
public void invoke(String origin, boolean allow, boolean retain);
參數說明:@param origin 使用權限設定的源地址@param allow 是否允許定位@retain 當前的選擇是否讓核心記住。
public void onGeolocationPermissionsHidePrompt()
public void openFileChooser(ValueCallback uploadFile, String acceptType, String capture)
這個回調是私人回調, 當頁面需要請求開啟系統的檔案選取器,則會回調這個方法,比如我們需要上傳圖片,請求拍照,郵件的附件上傳等等操作。如果不實現這個私人API,則上面的請求都將不會執行。
有問題歡迎討論。