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;  
    }   
}