WebView開發詳解(二)

概覽:

   Android WebView 做爲承載網頁的載體控件,他在網頁顯示的過程中會產生一些事件,並回調給我們的應用程序,以便我們在網頁加載過程中做應用程序想處理的事情。比如說客戶端需要顯示網頁加載的進度、網頁加載發生錯誤等等事件。 WebView提供兩個事件回調類給應用層,分別爲WebViewClient,WebChromeClient開發者可以繼承這兩個類,接手相應事件處理。WebViewClient 主要提供網頁加載各個階段的通知,比如網頁開始加載onPageStarted,網頁結束加載onPageFinished等;WebChromeClient主要提供網頁加載過程中提供的數據內容,比如返回網頁的title,favicon等。

1.WebViewClient的基本使用

 創建WebViewClient實例並設置到WebView對象中,具體代碼參考如下:
[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. class MyAndroidWebViewClient extends WebViewClient {  
  2.      @Override  
  3.     public void onPageStarted(WebView view, String url, Bitmap favicon) {  
  4.        // TODO  
  5.     }  
  6.   
  7.     @Override  
  8.     public void onPageFinished(WebView view, String url) {  
  9.       // TODO  
  10.     }  
[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. }  
  2. webview.setWebViewClient(new MyAndroidWebViewClient ());  

2.WebViewClient API詳解

1)網頁加載時機部分
     
[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  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。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. 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不一定每次都被調用,只有需要的時候纔會被調用。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onPageFinished(WebView view, String url)  

當內核加載完當前頁面時會通知我們的應用程序,這個函數只有在main frame情況下才會被調用,當調用這個函數之後,渲染的圖片不會被更新,如果需要獲得新圖片的通知可以使用@link WebView.PictureListener#onNewPicture。

參數說明:
@param view 接收WebViewClient的那個實例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。
@param url    即將要被加載的url

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onLoadResource(WebView view, String url)  
通知應用程序WebView即將加載url 制定的資源

參數說明:
@param view 接收WebViewClient的那個實例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。
@param url    即將加載的url 資源

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public WebResourceResponse shouldInterceptRequest(WebView view,  
  2.             String url)  
通知應用程序內核即將加載url制定的資源,應用程序可以返回本地的資源提供給內核,若本地處理返回數據,內核不從網絡上獲取數據。

參數說明:
@param view 接收WebViewClient的那個實例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。
@param url    raw url 制定的資源
@return 返回WebResourceResponse包含數據對象,或者返回null

Tips
這個回調並不一定在UI線程執行,所以我們需要注意在這裏操作View或者私有數據相關的動作。
如果我們需要改變網頁的背景,或者需要實現網頁頁面顏色定製化的需求,可以在這個回調時機處理。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onReceivedError(WebView view, int errorCode,  
  2.             String description, String failingUrl)  
當瀏覽器訪問制定的網址發生錯誤時會通知我們應用程序,比如網絡錯誤。

參數說明:
@param view 接收WebViewClient的那個實例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。
@param errorCode 錯誤號可以在WebViewClient.ERROR_* 裏面找到對應的錯誤名稱。
@param description 描述錯誤的信息
@param failingUrl  當前訪問失敗的url,注意並不一定是我們主url

Tips
在onReceiveError我們可以自定義網頁的錯誤頁面。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onFormResubmission(WebView view, Message dontResend,  
  2.             Message resend)  
如果瀏覽器需要重新發送POST請求,可以通過這個時機來處理。默認是不重新發送數據。
參數說明:
@param view 接收WebViewClient的那個實例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。
@param dontResent 當瀏覽器不需要重新發送數據時,可以使用這個參數。
@param resent 當瀏覽器需要重新發送數據時, 可以使用這個參數。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void doUpdateVisitedHistory(WebView view, String url,  
  2.             boolean isReload)  

通知應用程序可以將當前的url存儲在數據庫中,意味着當前的訪問url已經生效並被記錄在內核當中。這個函數在網頁加載過程中只會被調用一次。注意網頁前進後退並不會回調這個函數。
參數說明:
@param view 接收WebViewClient的那個實例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。
@param url 當前正在訪問的url 
@ param isReload 如果是true 這個是正在被reload的url


[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onReceivedSslError(WebView view, SslErrorHandler handler,  
  2.             SslError error)  

當網頁加載資源過程中發現SSL錯誤會調用此方法。我們應用程序必須做出響應,是取消請求handler.cancel(),還是繼續請求handler.proceed();內核的默認行爲是handler.cancel();

參數說明:
@param view 接收WebViewClient的那個實例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。
@param handler 處理用戶請求的對象。
@param error  SSL錯誤對象

Tips
內核會記住本次選擇,如果下次還有相同的錯誤,內核會直接執行之前選擇的結果。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onReceivedHttpAuthRequest(WebView view,  
  2.             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 認真請求所在的域

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. 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處理。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onScaleChanged(WebView view, float oldScale, float newScale)  
通知應用程序webview 要被scale。應用程序可以處理改事件,比如調整適配屏幕。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onReceivedLoginRequest(WebView view, String realm,  
  2.             String account, String args)  

通知應用程序有個自動登錄的帳號過程
參數說明:
@param view 請求登陸的webview
@param realm 賬戶的域名,用來查找賬戶。
@param account 一個可選的賬戶,如果是null 需要和本地的賬戶進行check, 如果是一個可用的賬戶,則提供登錄。
@param  args  驗證制定參數的登錄用戶

3.WebChromeClient 基本使用

4. WebChromeClient API詳解

創建WebChromeClient實例並設置到WebView對象中,具體代碼參考如下:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onProgressChanged(WebView view, int newProgress)  
通知應用程序當前網頁加載的進度。
參數說明:
@param view 接收WebViewClient的那個實例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onReceivedTitle(WebView view, String title)  

當document 的title變化時,會通知應用程序
參數說明:
@param view 接收WebViewClient的那個實例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。
@param title  document新的title
Tips
這個函數調用時機不確定,有可能很早,有可能很晚,取決於網頁把title設置在什麼位置,大多數網頁一般把title設置到頁面的前面,因此很多情況會比較早回調到這個函數。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onReceivedIcon(WebView view, Bitmap icon)  

當前頁面有個新的favicon時候,會回調這個函數。
參數說明:
@param view 接收WebViewClient的那個實例,前面看到webView.setWebViewClient(new MyAndroidWebViewClient()),即是這個webview。
@param icon 當前頁面的favicon

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onReceivedTouchIconUrl(WebView view, String url,  
  2.             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。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onShowCustomView(View view, CustomViewCallback callback)  

通知應用程序webview需要顯示一個custom view,主要是用在視頻全屏HTML5Video support。
參數說明:
@param view 即將要顯示的view
@param callback  當view 需要dismiss 則使用這個對象進行回調通知。


[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onHideCustomView()  
退出視頻通知

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public boolean onCreateWindow(WebView view, boolean isDialog,  
  2.             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 具體例子如下:
[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1.   private void createWindow(final Message msg) {  
  2. WebView.WebViewTransport transport = (WebView.WebViewTransport) msg.obj;  
  3. final Tab newTab = mWebViewController.openTab(null, Tab.thistrue,  
  4.         true);  
  5. transport.setWebView(newTab.getWebView());  
  6. msg.sendToTarget();  
  7.   }  

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onRequestFocus(WebView view)  
webview請求得到focus,發生這個主要是當前webview不是前臺狀態,是後臺webview。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onCloseWindow(WebView window)  

通知應用程序從關閉傳遞過來的webview並從view tree中remove。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public boolean onJsAlert(WebView view, String url, String message,  
  2.             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住。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public boolean onJsConfirm(WebView view, String url, String message,  
  2.             JsResult result)  

通知應用程序提供confirm 對話框。
參數說明同上onJsAlert

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public boolean onJsPrompt(WebView view, String url, String message,  
  2.             String defaultValue, JsPromptResult result)  

通知應用程序顯示一個prompt對話框。 
Tips
必須調用result.confirm 方法如果應用程序接管這個方法。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public boolean onJsBeforeUnload(WebView view, String url, String message,  
  2.             JsResult result)  
通知應用程序顯示一個對話框,讓用戶選擇是否離開當前頁面,這個回調是javascript中的onbeforeunload事件,如果客戶端返回true,內核會認爲客戶端提供對話框。默認行爲是return false。
參數說明和之前介紹的onJsAlert()相同。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onExceededDatabaseQuota(String url, String databaseIdentifier,  
  2.             long quota, long estimatedDatabaseSize, long totalQuota,  
  3.             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);配置新的數據庫配額大小。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onReachedMaxAppCacheSize(long requiredStorage, long quota,  
  2.             WebStorage.QuotaUpdater quotaUpdater)  

 通知應用程序內核已經到達最大的appcache。
appcache是HTML5針對offline的一個數據處理標準。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onGeolocationPermissionsShowPrompt(String origin,  
  2.             GeolocationPermissions.Callback callback)  

當前頁面請求是否允許進行定位。

GeolocationPermissions.Callback的使用

public void invoke(String origin, boolean allow, boolean retain);

參數說明:
@param origin 權限設置的源地址
@param allow 是否允許定位
@retain 當前的選擇是否讓內核記住。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void onGeolocationPermissionsHidePrompt()  

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public void openFileChooser(ValueCallback<Uri> uploadFile, String acceptType, String capture)  
這個回調是私有回調, 當頁面需要請求打開系統的文件選擇器,則會回調這個方法,比如我們需要上傳圖片,請求拍照,郵件的附件上傳等等操作。
如果不實現這個私有API,則上面的請求都將不會執行。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章