WebView介紹

本文主要對WebView進行介紹,包括webView 4個可以定製的點設置WebView back鍵響應控制網頁的鏈接仍在webView中跳轉顯示頁面加載進度處理https請求利用addJavascriptInterface實現android程序和javascript交互等等

WebView基於webkit引擎展現web頁面的控件,使用前需要在Android Manifest file中配置internet訪問權限,否則提示頁面無法訪問
Xml代碼  [url=][/url]

  • <uses-permission
    android:name="android.permission.INTERNET"
    />

WebView控件功能強大,除了具有一般View的屬性和設置外,還可以對url請求、頁面加載、渲染、頁面交互進行強大的處理。
WebView有幾個可以定製的點:
(1)設置WebChromeClient子類,WebChromeClient會在一些影響瀏覽器ui交互動作發生時被調用,比如WebView關閉和隱藏、頁面加載進展、js確認框和警告框、js加載前、js操作超時、webView獲得焦點等等,詳見WebChromeClient

(2)設置WebViewClient子類,WebViewClient會在一些影響內容喧嚷的動作發生時被調用,比如表單的錯誤提交需要重新提交、頁面開始加載及加載完成、資源加載中、接收到http認證需要處理、頁面鍵盤響應、頁面中的url打開處理等等,詳見WebViewClient

(3)設置WebSettings類,其中包含多項配置。WebSettings用來對WebView的配置進行配置和管理,比如是否可以進行文件操作、緩存的設置、頁面是否支持放大和縮小、是否允許使用數據庫api、字體及文字編碼設置、是否允許js腳本運行、是否允許圖片自動加載、是否允許數據及密碼保存等等,詳見WebSettings

(4)設置addJavascriptInterface方法,將java對象綁定到webView中,以方便從頁面js中控制java對象,實現用本地java代碼和html頁面進行交互,甚至可以進行頁面自動化。但如此做存在安全隱患,所以若設置了此方法,請確保webView的代碼都是自己完成,詳細使用addJavascriptInterface進行自動化見本文5使用addJavascriptInterface完成和js交互

1、back鍵控制網頁後退
Activity默認的back鍵處理爲結束當前Activity,webView查看了很多網頁後,希望按back鍵返回上一次瀏覽的頁面,這個時候我們就需要覆蓋onKeyDown函數,告訴他如何處理,如下:
Java代碼  [url=][/url]

  • public
    boolean onKeyDown(int keyCode, KeyEvent event) {  
  •     if (webView.canGoBack() && event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {  
  •         webView.goBack();  
  •         return
    true;  
  •     }  

  •     return
    super.onKeyDown(keyCode, event);  
  • }  

其中webView.canGoBack()在webView含有一個可後退的瀏覽記錄時返回true
webView.goBack();表示返回webView的上次訪問頁面

2、當前網頁的鏈接仍在webView中跳轉
Java代碼  [url=][/url]

  • webView.setWebViewClient(new WebViewClient() {  

  •     @Override
  •     public
    boolean shouldOverrideUrlLoading(WebView view, String url) {  
  •         view.loadUrl(url);  
  •         return
    true;  
  •     }  
  • });  

shouldOverrideUrlLoading表示當前webView中的一個新url需要加載時,給當前應用程序一個處理機會,如果沒有重寫此函數,webView請求ActivityManage選擇合適的方式處理請求,就像彈出uc和互聯網讓用戶選擇瀏覽器一樣。重寫後return true表示讓當前程序處理,return false表示讓當前webView處理
Xml代碼  [url=][/url]

  • Give the host application a chance to take over the control when a new url is about to be loaded in the current WebView. If WebViewClient is not provided, by default WebView will ask Activity Manager to choose the proper handler for the url. If WebViewClient is provided, return true means the host application handles the url, while return false means the current WebView handles the url.  

參考:
http://developer.android.com/reference/android/webkit/WebViewClient.html#shouldOverrideUrlLoading(android.webkit.WebView, java.lang.String)

問題分析:
今天在用webView load騰訊的OAuth頁面http://open.t.qq.com/cgi-bin/authorize
時,突然彈出選擇uc還是互聯網瀏覽器的確認框,很奇怪,其他頁面都能正常load,而這個卻無法在webView中load,後來用火狐看了下是因爲load這個頁面的時候會重定向到另外一個頁面http://open.t.qq.com/oauth_html/login.php?oauth_token=xxx&type=0,而webView沒有設置shouldOverrideUrlLoading,導致url交給了ActivityManage去處理,解釋如上,後添加後可正常load頁面

3、頁面加載進度
代碼如下
Java代碼  [url=][/url]

  • webView.setWebChromeClient(new WebChromeClient() {  

  •     public
    void onProgressChanged(WebView view, int progress) {  
  •         setTitle("頁面加載中,請稍候..." + progress + "%");  
  •         setProgress(progress * 100);  

  •         if (progress == 100) {  
  •             setTitle(R.string.app_name);  
  •         }  
  •     }  
  • });  

onProgressChanged通知應用程序當前頁面加載的進度
progress
表示當前頁面加載的進度,爲1至100的整數
參考:
http://developer.android.com/reference/android/webkit/WebChromeClient.html#onProgressChanged(android.webkit.WebView, int)

4、處理https請求
webView默認是不處理https請求的,頁面顯示空白,需要進行如下設置:
Java代碼  [url=][/url]

  •     webView.setWebViewClient(new WebViewClient() {  

  •         @Override
  •         public
    void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {  
  •             handler.proceed();  
  • //            handler.cancel();
  • //            handler.handleMessage(null);
  •         }  
  •     });  

onReceivedSslError爲webView處理ssl證書設置
其中handler.proceed();表示等待證書響應
handler.cancel();表示掛起連接,爲默認方式
handler.handleMessage(null);可做其他處理
參考:
http://developer.android.com/reference/android/webkit/WebViewClient.html#onReceivedSslError(android.webkit.WebView, android.webkit.SslErrorHandler, android.net.http.SslError)

5、使用addJavascriptInterface完成和js交互
5.1 javascript中調用java對象及方法
設置webView的addJavascriptInterface方法,該方法有兩個參數,第一個參數爲被綁定到js中的類實例,第二個參數爲在js中暴露的類別名,在js中引用java對象就是用這個名字
Java代碼  [url=][/url]

  • ClassBeBindedToJS classBeBindedToJS = new ClassBeBindedToJS();  
  • webView.addJavascriptInterface(classBeBindedToJS, "classNameBeExposedInJs");   


實現綁定到js的類,其中的javaMethod方法我們將在頁面前端js中調用,用於返回一段內容。showHtml用來使用AlertDialog顯示一段html代碼,稍後將使用到
Java代碼  [url=][/url]

  • private
    class ClassBeBindedToJS{  
  •     public
    void showHtml(String html){  
  •          new AlertDialog.Builder(UpdateStatusActivity.this)   
  •                      .setTitle("HTML").setMessage(html)  
  •                      .setPositiveButton(android.R.string.ok, null)  
  •                      .setCancelable(false).create().show();  
  •     }  
  •     public String javaMethod() {  
  •         return
    "use java method";  
  •     }  
  • };  

如此我們就可以在前端調用java對象,如下:
Html代碼  [url=][/url]

  • <span><html>
  •     <body>
  •         <div
    id="displayDiv">Test page.</div>
  •         <input
    type="button"
    value="use java object"
    οnclick="document.getElementById('</span>displayDiv').innerHTML=classNameBeExposedInJs.javaMethod()"
    />
  • <span>
    </body>
  • </html></span>

這段html作用爲點擊button按鈕,改變div內容爲java對象方法中的內容,其中classNameBeExposedInJs爲java對象在js中的別名,javaMethod爲java對象的方法

5.2 java中調用js方法
用webView的loadUrl實現,比如現在我們想在頁面加載完成後調用js中的hello函數,實現如下:
Java代碼  [url=][/url]

  • webView.setWebViewClient(new WebViewClient() {   
  •     @Override
  •     public
    void onPageFinished(WebView webView, String url){  
  •         webView.loadUrl("javascript:hello()");  
  •     }  
  • });  

怎麼樣,很簡單吧^_^,直接loadUrl("javascript:hello()")就可以了 
利用這一點我們可以很方便的實現WebView的自動化,如網頁自動化登錄。舉個栗子,實現http://m.renren.com/ 的自動登錄啊,代碼如下
Java代碼  [url=][/url]

  • webView.getSettings().setJavaScriptEnabled(true);  
  • webView.loadUrl("http://m.renren.com");  
  • webView.requestFocus();  

  • ClassBeBindedToJS classBeBindedToJS = new ClassBeBindedToJS();  
  • webView.addJavascriptInterface(classBeBindedToJS, "classNameBeExposedInJs");      
  • webView.setWebViewClient(new WebViewClient() {   
  •     @Override
  •     public
    void onPageFinished(WebView webView, String url){   
  •         webView.loadUrl("javascript:document.getElementsByName('email')[0].value='userName'");   
  •         webView.loadUrl("javascript:document.getElementsByName('password')[0].value='userPassword'");   
  •         webView.loadUrl("javascript:document.getElementsByName('login')[0].click()");  
  •     }  
  • });  

從中可以看出先加載http://m.renren.com頁面,在頁面加載完成onPageFinished後,調用js實現自動登錄
其中三句js分別表示設置用戶名文本框內容、設置用戶密碼文本框內容、點擊登錄按鈕,如此登錄成功嘍

5.3 java和js混用實現一些效果
5.3.1 WebView用AlertDialog顯示頁面的html代碼
之前5.1中的showHtml方法現在派上用場啦,在頁面加載完成後顯示頁面html內容,如下:
Java代碼  [url=][/url]

  • webView.setWebViewClient(new WebViewClient() {   
  •     @Override
  •     public
    void onPageFinished(WebView webView, String url){  
  •         webView.loadUrl("javascript:window.classNameBeExposedInJs.showHtml(document.getElementsByTagName('html')[0].innerHTML);");  
  •     }  
  • });  

其中webView.loadUrl表示調用頁面中的js,而頁面中的js window.classNameBeExposedInJs.showHtml調用了程序中的java對象的方法,方法參數爲一段js。
首先webView會執行這一段js document.getElementsByTagName('html')[0].innerHTML。含義即爲取得頁面中html標記的innerHTML,及網頁主要內容;
然後將得到的網頁內容當作字符串參數傳入showHtml方法
最後調用showHtml函數實現,即用AlertDialog顯示字符串,如此得到了整個網頁的大部分html代碼

5.3.2 WebView顯示當前頁面的url地址
獲得WebView當前頁面url使用webView.getUrl()即可,如下:
Java代碼  [url=][/url]

  • webView.loadUrl("javascript:window.classNameBeExposedInJs.showHtml('" + webView.getUrl() + "');");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章