1.Android WebView 一些基本概念
在 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);
3.如果页面中链接,如果希望点击链接继续在当前 browser 中响应,而不是新开 Android 的系统 browser 中响应该链接,必须覆盖 WebView 的 WebViewClient 对象.
mWebView.setWebViewClient(new WebViewClient() { public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } });
4.如果不做任何处理,浏览网页,点击系统“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); }
下一步让我们来了解一下 android 中 WebView 是如何支持 javascripte 自定义对象的,在 w3c 标准中 js 有window ,history ,document 等标准对象,同样我们可以在开发浏览器时自己定义我们的对象调用手机系统功能来处理,这样使用 js 就可以为所欲为了.
看一个实例:
public class WebViewDemo extends Activity { private WebView mWebView; private Handler mHandler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); 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"); } }
我们看 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 的目的.
2.Android WebView 组件的使用详解
网络内容
1、LoadUrl 直接显示网页内容(单独显示网络图片)
2、LoadData 显示中文网页内容(含空格的处理)
APK 包内文件
1、LoadUrl 显示 APK 中 Html 和图片文件
2、LoadData(loadDataWithBaseURL)显示 APK 中图片和文字混合的 Html 内容
res/layout/main.xml
Xml 代码
< ?xml version="1.0" encoding="utf-8"?> < LINEARLAYOUT android : layout_height="fill_parent" android : layout_width="fill_parent" android : orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"> < WebView android : layout_height="fill_parent" android : layout_width="fill_parent" android : id="@+id/WebView" /> < /LINEARLAYOUT> < ?xml version="1.0" encoding="utf-8"?> < LINEARLAYOUT android : layout_height="fill_parent" android : layout_width="fill_parent" android : orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android"> < WebView android : layout_height="fill_parent" android : layout_width="fill_parent" android : id="@+id/WebView" /> < /LINEARLAYOUT>
Java代码
public class Example_WebView extends Activity { WebView WebView; final String mimeType = "text/html"; final String encoding = "utf-8"; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main); WebView = (WebView) findViewById(R.id.WebView); WebView.getSettings().setJavaScriptEnabled(true); // //webHtml(); // //webImage(); // //localHtmlZh(); // //localHtmlBlankSpace(); // //localHtml(); // // localImage(); // localHtmlImage(); } /** * 直接网页显示 */ private void webHtml() { try { WebView.loadUrl("http://www .google.com"); } catch (Exception ex) { ex.printStackTrace(); } } /** * 直接网络图片显示 */ private void webImage() { try { WebView .loadUrl("http://www .gstatic.com/codesite/ph/images/code_small.png"); } catch (Exception ex) { ex.printStackTrace(); } } /** * 中文显示 */ private void localHtmlZh() { try { String data = "测试含有 中文的 Html 数据"; // utf-8 编码处理(在 SDK1.5 模拟器和真实设备上都将出现乱码,SDK1.6 上能正常显示) //WebView.loadData(data, mimeType, encoding); // 对数据进行编码处理(SDK1.5 版本) WebView.loadData(URLEncoder .encode(data, encoding), mimeType, encoding); } catch (Exception ex) { ex.printStackTrace(); } } /** * 中文显示(空格的处理) */ private void localHtmlBlankSpace() { try { String data = " 测试含有空格的 Html 数据 "; // 不对空格做处理 WebView.loadData(URLEncoder .encode(data, encoding), mimeType, encoding); //WebView.loadData(data, mimeType, encoding); // 对空格做处理(在 SDK1.5 版本中) WebView.loadData(URLEncoder .encode(data, encoding).replaceAll( "\+", " "), mimeType, encoding); } catch (Exception ex) { ex.printStackTrace(); } } /** * 显示本地图片文件 */ private void localImage() { try { // 本地文件处理(如果文件名中有空格需要用+来替代) WebView.loadUrl("file:///android_asset/icon.png"); } catch (Exception ex) { ex.printStackTrace(); } } /** * 显示本地网页文件 */ private void localHtml() { try { // 本地文件处理(如果文件名中有空格需要用+来替代) WebView.loadUrl("file:///android_asset/test.html"); } catch (Exception ex) { ex.printStackTrace(); } } /** * 显示本地图片和文字混合的 Html 内容 */ private void localHtmlImage() { try { String data = "测试本地图片和文字混合显示,这是 APK 里的图片"; // SDK1.5 本地文件处理(不能显示图片) // WebView.loadData(URLEncoder .encode(data, encoding), mimeType,// encoding); // SDK1.6 及以后版本 // WebView.loadData(data, mimeType, encoding); // 本地文件处理(能显示图片) WebView.loadDataWithBaseURL("about:blank", data, mimeType, encoding, ""); } catch (Exception ex) { ex.printStackTrace(); } }
webView的简介就到这了,如有不正确的地方,欢迎指正。