Android:WebKit介绍
WebKit是一个开源的浏览器网页排版引擎,包含WebCore排版引擎和JSCore引擎。
WebCore和JSCore引擎来自于KDE项目的KHTML和KJS开源项目。Android平台的Web
引擎框架采用了WebKit项目中的WebCore和JSCore部分,上层由Java语言封装,并且作
为API提供给Android应用开发者,而底层使用WebKit核心库(WebCore和JSCore)进行网页排版。
Android平台的 WebKit模块分成 Java和 WebKit库两个部分,其目录结构如下表所示:
WebKit 模块目录结构 | |
Java 层(根目录 device\java\android\android\webkit ) | |
BrowserFrame.java | BrowserFrame对象是对 WebCore库中的 Frame对象的 Java层封装,用于创建 WebCore中定义的 Frame,以及为该 Frame对象提供 Java层回调方法。 |
ByteArrayBuilder.java | ByteArrayBuilder辅助对象,用于 byte块链表的处理。 |
CachLoader.java | URL Cache载入器对象,该对象实现 StreadLoader抽象基类,用于通过 CacheResult对象载入内容数据。 |
CacheManager.java | Cache管理对象,负责 Java层 Cache对象管理 |
CacheSyncManager.java | Cache同步管理对象,负责同步 RAM和 FLASH之间的浏览器 Cache数据。实际的物理数据操作在 WebSyncManager对象中完成。 |
CallbackProxy.java | 该对象是用于处理 WebCore与 UI线程消息的代理类。当有 Web事件产生时 WebCore线程会调用该回调代理类,代理类会通过消息的方式通知 UI线程,并且调用设置的客户对象的回调函数。 |
CellList.java | CellList定义图片集合中的 Cell,管理 Cell图片的绘制、状态改变以及索引。 |
CookieManager.java | 根据 RFC2109规范,管理 cookies |
CookieSyncManager.java | Cookies同步管理对象,该对象负责同步 RAM和 Flash之间的 Cookies数据。实际的物理数据操作在基类 WebSyncManager中完成。 |
DataLoader.java | 数据载入器对象,用于载入网页数据。 |
DateSorter.java | 尚未使用 |
DownloadListener.java | 下载侦听器接口 |
DownloadManagerCore.java | 下载管理器对象,管理下载列表。该对象运行在 WebKit的线程中,通过 CallbackProxy对象与 UI线程交互。 |
FileLoader.java | 文件载入器,将文件数据载入到 Frame中。 |
FrameLoader.java | Frame载入器,用于载入网页 Frame数据 |
HttpAuthHandler.java | Http认证处理对象,该对象会作为参数传递给 BrowserCallback.displayHttpAuthDialog方法,与用户交互。 |
HttpDataTime.java | 该对象是处理 HTTP日期的辅助对象。 |
JsConfirmResult.java | Js确认请求对象 |
JsPromptResult.java | Js结果提示对象,用于向用户提示 Javascript运行结果。 |
JsResult.java | Js结果对象,用于用户交互 |
JWebCoreJavaBridge.java | 用 Java与 WebCore库中 Timer和 Cookies对象交互的桥接代码。 |
LoadListener.java | 载入器侦听器,用于处理载入器侦听消息。 |
Network.java | 该对象封装网络连接逻辑,为调用者提供更为高级的网络连接接口。 |
PanZoom.java | 用于处理图片缩放、移动等操作 |
PanZoomCellList.java | 用于保存移动、缩放图片的 Cell |
PerfChecker.java | 用于效率测试的功能对象??? |
SslErrorHandler.java | 用于处理 SSL错误消息。 |
StreamLoader.java | StreamLoader抽象类是所有内容载入器对象的基类。该类是通过消息方式控制的状态机,用于将数据载入到 Frame中。 |
TextDialog.java | 用于处理 html中文本区域叠加情况,可以使用标准的文本编辑而定义的特殊 EditText控件。 |
URLUtil.java | URL处理功能函数,用于编码、解码 URL字符串,以及提供附加的 URL类型分析功能。 |
WebBackForwardList.java | 该对象包含 WebView对象中显示的历史数据。 |
WebBackForwardListClient.java | 浏览历史处理的客户接口类,所有需要接收浏览历史改变的类都需要实现该接口。 |
WebChromeClient.java | Chrome客户基类, Chrome客户对象在浏览器文档标题、进度条、图标改变时候会得到通知。 |
WebHistoryItem.java | 该对象用于保存一条网页历史数据 |
WebIconDataBase.java | 图表数据库管理对象,所有的 WebView均请求相同的图标数据库对象。 |
WebSettings.java | WebView的管理设置数据,该对象数据是通过 JNI接口从底层获取。 |
WebSyncManager.java | 数据同步对象,用于 RAM数据和 FLASH数据的同步操作。 |
WebView.java | Web视图对象,用于基本的网页数据载入、显示等 UI操作。 |
WebViewClient.java | Web视图客户对象,在 Web视图中有事件产生时,该对象可以获得通知。 |
WebViewCore.java | 该对象对 WebCore库进行了封装,将 UI线程中的数据请求发送给 WebCore处理,并且通过 CallbackProxy的方式,通过消息通知 UI线程数据处理的结果。 |
WebViewDatabase.java | 该对象使用 SQLiteDatabase为 WebCore模块提供数据存取操作。 |
Android平台的 WebKit模块由 Java层和 WebKit库两个部分组成, Java层负责与 Android应用程序进行通信,而 WebKit类库负责实际的网页排版处理。 Java层和 C层库之间通过 JNI和 Bridge相互调用,如下图所示:
Android:使用WebView浏览网页
Android中,提供了WebKit引擎用于对网页浏览和操作进行编程。Google对WebKit进行了封装,提供了丰富的Java接口,其中最重要的便是android.webkit.WebView。WebView类是WebKit模块Java层的视图类,所有需要使用Web浏览器功能,都需要创建该类对象显示和处理请求网络资源。
实现WebView的方法:
1.在要Activity中实例化WebView组件:WebView webView = new WebView(this);
或者在布局文件中声明WebView。
2.调用WebView的loadUrl()方法,设置WevView要显示的网页:
互联网用:webView.loadUrl("http://www.google.com");
本地文件用:webView.loadUrl("file:///android_asset/XX.html");本地文件存放在:assets 文件中
3.调用Activity的setContentView( )方法来显示网页视图
4.用WebView点链接看了很多页以后为了让WebView支持回退功能,需要覆盖覆盖Activity类的onKeyDown()方法,如果不做任何处理,点击系统回退键,整个浏览器会调用finish()而结束自身,而不是回退到上一页面
5.需要在AndroidManifest.xml文件中添加权限,否则会出现Web page not available错误。
<uses-permission android:name="android.permission.INTERNET"/>
下面是具体例子:
MainActivity.java
package com.android.webview.activity;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
public class MainActivity extends Activity {
private WebView webview;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//实例化WebView对象
webview = new WebView(this);
//设置WebView属性,能够执行Javascript脚本
webview.getSettings().setJavaScriptEnabled(true);
//加载需要显示的网页
webview.loadUrl("http://www.51cto.com/");
//设置Web视图
setContentView(webview);
}
@Override
//设置回退
//覆盖Activity类的onKeyDown(int keyCoder,KeyEvent event)方法
public boolean onKeyDown(int keyCode, KeyEvent event){
if ((keyCode ==KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
webview.goBack(); //goBack()表示返回WebView的上一页面
returntrue;
}
return false;
}
在AndroidManifest.xml文件添加权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.webview.activity"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10" />
<application android:icon="@drawable/icon"android:label="@string/app_name">
<activityandroid:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permissionandroid:name="android.permission.INTERNET"/>
</manifest>
效果图:
Android:WebView与Javascript
下面这个小例子介绍了怎样通过WebView实现java与Js的双向调用。
1.首先是布局文件main.xml
Xml代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<WebView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/webView"
/>
</LinearLayout>
<?xmlversion="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<WebView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/webView"
/>
</LinearLayout>
=
2.在assets目录下新建一个index.html文件
Html代码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<script type="text/javascript">
//data数据类型为字符串,字符串里面是数组,每一个数组元素为一个json对象,例如"[{id:1,name:'张三',phone:'135656461'},{id:2,name:'李四',phone:'1896561'}]"
function setContactInfo(data)
{
tableObj = document.getElementById("contact");
jsonObjects = eval(data); //通过eval方法处理得到json对象数组
i=0; i<jsonObjects.length; i++)
{
jsonObj = jsonObjects[i]; //获取json对象
tr = tableObj.insertRow(tableObj.rows.length); //添加一行
//添加三列
td1 = tr.insertCell(0);
td2 = tr.insertCell(1);
td3 = tr.insertCell(2);
td1.innerHTML = jsonObj.id;
td2.innerHTML = jsonObj.name;
td3.innerHTML = jsonObj.phone;
}
}
</script>
</head>
<!--οnlοad="javascript:myObject.init()调用服务器端init方法-->
<body onload="javascript:myObject.init()">
<table id="contact">
<tr>
<td>编号</td>
<td>姓名</td>
<td>电话</td>
</tr>
</table>
</body>
</html>
<!DOCTYPE HTML PUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<scripttype="text/javascript">
//data数据类型为字符串,字符串里面是数组,每一个数组元素为一个json对象,例如"[{id:1,name:'张三',phone:'135656461'},{id:2,name:'李四',phone:'1896561'}]"
function setContactInfo(data)
{
var tableObj = document.getElementById("contact");
var jsonObjects = eval(data); //通过eval方法处理得到json对象数组
for(var i=0;i<jsonObjects.length; i++)
{
var jsonObj =jsonObjects[i]; //获取json对象
var tr = tableObj.insertRow(tableObj.rows.length); //添加一行
//添加三列
var td1 = tr.insertCell(0);
var td2 = tr.insertCell(1);
var td3 = tr.insertCell(2);
td1.innerHTML = jsonObj.id;
td2.innerHTML =jsonObj.name;
td3.innerHTML =jsonObj.phone;
}
}
</script>
</head>
<!--οnlοad="javascript:myObject.init()调用服务器端init方法-->
<bodyοnlοad="javascript:myObject.init()">
<table id="contact">
<tr>
<td>编号</td>
<td>姓名</td>
<td>电话</td>
</tr>
</table>
</body>
</html>
3.接着是Activity
Java代码
package com.lamp.activity;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.webkit.WebView;
public class HTMLActivity extends Activity {
private WebView webView = null;
public Handler handler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webView = (WebView)this.findViewById(R.id.webView);
//设置字符集编码
webView.getSettings().setDefaultTextEncodingName("UTF-8");
//开启JavaScript支持
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new MyObject(this,handler), "myObject");
//加载assets目录下的文件
String url = "file:///android_asset/index.html";
webView.loadUrl(url);
}
}
package com.lamp.activity;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.webkit.WebView;
public class HTMLActivityextends Activity {
private WebView webView = null;
public Handler handler = new Handler();
@Override
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webView =(WebView)this.findViewById(R.id.webView);
//设置字符集编码
webView.getSettings().setDefaultTextEncodingName("UTF-8");
//开启JavaScript支持
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(newMyObject(this,handler), "myObject");
//加载assets目录下的文件
String url ="file:///android_asset/index.html";
webView.loadUrl(url);
}
}
4.然后是绑定js的类MyObject
Java代码
package com.lamp.activity;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.Handler;
import android.webkit.WebView;
public class MyObject {
private Handler handler = null;
private WebView webView = null;
public MyObject(HTMLActivity htmlActivity, Handler handler) {
this.webView = (WebView)htmlActivity.findViewById(R.id.webView);
this.handler = handler;
}
public void init(){
//通过handler来确保init方法的执行在主线程中
handler.post(new Runnable() {
public void run() {
//调用客户端setContactInfo方法
webView.loadUrl("javascript:setContactInfo('" + getJsonStr() + "')");
}
});
}
public static String getJsonStr(){
try {
JSONObject object1 = new JSONObject();
1);
object1.put("name", "张三");
object1.put("phone", "123456");
JSONObject object2 = new JSONObject();
2);
object2.put("name", "李四");
object2.put("phone", "456789");
JSONArray jsonArray = new JSONArray();
jsonArray.put(object1);
jsonArray.put(object2);
return jsonArray.toString();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}