轉自:http://www.cnblogs.com/oakpip/archive/2011/04/08/2009800.html
大部分內容為網上整理其它高人的帖子,現只作整理,用於查看:
在Android手機中內置了一款高性能webkit內核瀏覽器,在SDK中封裝為一個叫做WebView組件。
什么是webkit
WebKit是Mac OS X v10.3及以上版本所包含的軟件框架(對v10.2.7及以上版本也可通過軟件更新獲取)。 同時,WebKit也是Mac OS X的Safari網頁瀏覽器的基礎。WebKit是一個開源項目,主要由KDE的KHTML修改而來並且包含了一些來自蘋果公司的一些組件。
傳統上,WebKit包含一個網頁引擎WebCore和一個腳本引擎JavaScriptCore,它們分別對應的是KDE的KHTML和KJS。不過, 隨着JavaScript引擎的獨立性越來越強,現在WebKit和WebCore已經基本上混用不分(例如Google Chrome和Maxthon 3采用V8引擎,卻仍然宣稱自己是WebKit內核)。
這里我們初步體驗一下在android是使用webview瀏覽網頁,在SDK的Dev Guide中有一個WebView的簡單例子 。
在開發過程中應該注意幾點:
1.AndroidManifest.xml中必須使用許可"android.permission.INTERNET",否則會出Web page not available錯誤。
2.如果訪問的頁面中有Javascript,則webview必須設置支持Javascript。
webview.getSettings().setJavaScriptEnabled(true);
WebView默認是不支持JavaScript 、IFrame或者是任何的框架語法的。通過設webview.getSettings().setJavaScriptEnabled(true); 就可以打開JavaScript. webView.requestFocus()如果不設置的話,會出現不能彈出軟鍵盤等問題。
3.如果頁面中鏈接,如果希望點擊鏈接繼續在當前browser中響應,而不是新開Android的系統browser中響應該鏈接,必須覆蓋 webview的WebViewClient對象。
mWebView.setWebViewClient(new WebViewClient(){ public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } });
4. postUrl(String url, byte[] postData) 加載頁面使用Post方式,postData為參數
// post方式傳送參數 String postData = "clientID=cid&username=name"; webview.postUrl(url, EncodingUtils.getBytes(postData, "base64"));
5.如果不做任何處理,瀏覽網頁,點擊系統“Back”鍵,整個Browser會調用finish()而結束自身,如果希望瀏覽的網 頁回退而不是推出瀏覽器,需要在當前Activity中處理並消費掉該Back事件。
public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) { mWebView.goBack(); return true; } return super.onKeyDown(keyCode, event); }
6.事件偵聽
WebChromeClient:
onCloseWindow(關閉WebView)
onCreateWindow()
onJsAlert (WebView上alert是彈不出來東西的,需要定制你的WebChromeClient處理彈出)
onJsPrompt
onJsConfirm
onProgressChanged
onReceivedIcon
onReceivedTitle
WebViewClient:
onLoadResource:加載資源時響應
onPageStart:在加載頁面時響應
onPageFinish:在加載頁面結束時響應
onReceiveError:在加載出錯時響應
onReceivedHttpAuthRequest:
//此方法可以處理webview 在加載時和加載完成時一些操作 webView.setWebChromeClient(new WebChromeClient(){ @Override public void onProgressChanged(WebView view, int newProgress) { if(newProgress==100){ // 這里是設置activity的標題, 也可以根據自己的需求做一些其他的操作 title.setText("加載完成"); }else{ title.setText("加載中......."); } } }); webView.setWebViewClient(new WebViewClient(){ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { //重寫此方法表明點擊網頁里面的鏈接還是在當前的webview里跳轉,不跳到瀏覽器那邊 view.loadUrl(url); return true; } @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, android.net.http.SslError error) { // 重寫此方法可以讓webview處理https請求 handler.proceed(); } });
下一步讓我們來了解一下android中webview是如何支持javascripte自定義對象的,在w3c標准中js有 window,history,document等標准對象,同樣我們可以在開發瀏覽器時自己定義我們的對象調用手機系統功能來處理,這樣使用js就可以 為所欲為了。
看一個實例:
public class WebViewDemo extends Activity { private WebView mWebView; private Handler mHandler = new Handler(); public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.webviewdemo); mWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = mWebView.getSettings(); webSettings.setJavaScriptEnabled(true); mWebView.addJavascriptInterface(new Object() { public void clickOnAndroid() { mHandler.post(new Runnable() { public void run() { mWebView.loadUrl("javascript:wave()"); } }); } }, "demo"); mWebView.loadUrl("file:///android_asset/demo.html"); } }
打開自定義的html
String customHtml = "<html><body><h1>Hello, WebView</h1></body></html>"; webView.loadData(customHtml, "text/html", "UTF-8");
我們看addJavascriptInterface(Object obj,String interfaceName)這個方法,該方法將一個java對象綁定到一個javascript對象中,javascript對象名就是 interfaceName(demo),作用域是Global。這樣初始化webview后,在webview加載的頁面中就可以直接通過 javascript:window.demo訪問到綁定的java對象了。來看看在html中是怎樣調用的。
<html> <mce:script language="javascript"><!-- function wave() { document.getElementById("droid").src="android_waving.png"; } // --></mce:script> <body> <a onClick="window.demo.clickOnAndroid()"> <img id="droid" src="android_normal.png" mce_src="android_normal.png"/><br> Click me! </a> </body> </html>
這樣在javascript中就可以調用java對象的clickOnAndroid()方法了,同樣我們可以在此對象中定義很多方法(比 如發短信,調用聯系人列表等手機系統功能。),這里wave()方法是java中調用javascript的例子。
這里還有幾個知識點:
1)為了讓WebView從apk文件中加載assets,Android SDK提供了一個schema,前綴為"file:///android_asset/"。WebView遇到這樣的schema,就去當前包中的 assets目錄中找內容。如上面的"file:///android_asset/demo.html"
2)addJavascriptInterface方法中要綁定的Java對象及方法要運行另外的線程中,不能運行在構造他的線程中,這也是使用 Handler的目的。