当前位置:操作系统 > 安卓/Android >>

android 2.3 webkit

1.      前言

    大家对WebView应该不陌生, 它是Android里面用来显示网页的控件, 用它显示网页只需要几行代码, 如下:

public class WebViewDemoActivity extendsActivity {

   @Override

   public void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.main);  

       mWebView = (WebView) findViewById(R.id.webview);

       mWebView.loadUrl("http://www.zzzyk.com");   

    }

}

       这样在WebViewDemoActivity启动时就会显示出google的主页, 我们还可以在里面输入关键字进行搜索。究竟WebView的loadUrl函数里面究竟做了哪些事情呢?我们带着好奇心走进android的Webkit世界。

2.      加载网页过程的UML序列图

       这里先给出loadUrl整个过程的uml序列图, 然后再慢慢分析。 。

3.      WebKit介绍 
       前面提到了Webkit,那究竟Webkit是什么呢?它和我们所熟悉的WebView是什么关系呢?这里引用网上的解释:“WebKit是一个开源的浏览器网页排版引擎,包含WebCore排版引擎和JSCore引擎。WebCore和JSCore引擎来自于KDE项目的KHTML和KJS开源项目。Android平台的Web引擎框架采用了WebKit项目中的WebCore和JSCore部分,上层由Java语言封装,并且作为API提供给Android应用开发者,而底层使用WebKit核心库(WebCore和JSCore)进行网页排版。”可见,WebView就属于Android的Webkit提供给应用开发者用的上层API部分。
        很多伟大的软件都是可移植的,Webkit也不例外。目前Webkit支持Qt,Gtk,Android等等。大家都知道移植是有条件的,比如要将linux系统移植到某个硬件平台,那么这个硬件平台至少要有个硬件定时器来进行进程调度,要有mmu来支持虚拟内存管理,另外对系统ram和flash的空间也是有一定底线要求的。移植Webkit所要求的条件是什么呢?先分析Webkit加载网页的这样一个过程:
l        从网络上把url地址上的html文件下载到本地
l        词法分析和语法分析
l        绘制
       很明显,Webkit需要依赖平台相关的网络接口和图形接口,如下图所示:

    可移植的软件都可以分为两部分:平台相关代码和平台无关代码。这两部分之间的交互是通过固定接口来完成的,当然Webkit也不例外。对于Android Webkit,我们把它简单看为两部分:Android和WebCore。 Android到Webcore方向当然是直接调用的关系, 而WebCore有时也需要回调Android部分的代码, 这就需要通过WebCore定义的一套固定的接口来完成。如下图所示, ResourceHandle是WebCore获取网络资源的接口, Android平台对这个接口的实现是调用了Android API中的android.net.*包里面的类实现的。 GraphicContext是WebCore绘制页面的接口, Android平台对这个接口的实现是通过调用Android平台的2D绘图引擎Skia实现的。
 
 
 
4.      加载网页过程分析
    有一个很重要的概念需要解释一下,Frame,翻译成中文是“帧”,一个html页面构成如下图,即一个html页面包含一个MainFrame,MainFrame中又可以包含0到n个子Frame。一个Frame对应一个Url,在MainFrame里包含子Frame就意味着把子Frame的内容嵌入到MainFrame的一块空间里面。
      
        在WebKit里面有个结构体WebCore::Frame,这个数据结构就包含了,一个网页解析后的全部数据。下面就是从一个Url到生成一个MainFrame的过程。

       接下来就是要将Main frame里面的数据显示出来,这部分代码是每个平台的实现都是不同的,我们以Android为例。首先需要说明的是,Android Webkit加载网页是通过三个线程协作完成的:
l        UI线程:Android图形系统派发事件的线程,WebView的onDraw函数和onTouchEvent函数就是运行在这个线程。UI线程只做一些轻量级的工作,会将耗时的工作转给Webcore线程进行处理。
l        WebCore线程:在andriod.webkit.WebViewCore类中创建,负责html文件解析等任务。
l        下载线程:在android.webkit.WebViewWorker中创建,负责下载从指定url下载html。
      
       当调用WebView.loadUrl时线程协作图如下,UI线程向WebCore线程发送消息,WebCore线程接到消息会把下载任务交给下载线程,下载线程下载完毕后通知WebCore线程进行html的解析,WebCore线程解析完html后通知UI线程刷新界面。

       回顾一下这个图:

       Webcore线程就是通过ResourceHandleAndroid来启动下载线程下载html的,然后WebCore线程进行html解析,最后生成能够描述整个html页面的Main  frame,再通知UI线程绘制页面。假设UI线程在onDraw函数里需要通过分析Mainframe来绘图,那么很可能给人不流畅的感觉。所以WebCore线程在生成Frame结构体之后,又做了一个工作,就是解析Main frame并绘制到一块内存上面,而UI线程在onDraw时只需把这块内存上的内容绘制到屏幕上即可,这块内存叫PictureSet。Picture是一个图片集合,Main frame是Frame的集合,PictureSet里面的Picture和Main frame里面得Frame都是一一对应的关系。    
       还记得以前提到的代码层次吗?PictureSet是属于Webkit的Andriod移植层的,而Frame是属于WebCore层的,也就是说WebCore生成Frame后任务就完成了,然后会通过固定的接口通知Android移植层,Android移植层随后分析Frame来生成PictureSet。在PictureSet生成后才会通知UI线程更新界面,WebView.onDraw中便会将PictureSet绘制到画布上。
       最后需要补充说明的是,Android的Webkit移植层比其它平台相比多了jni部分,通过阅读代码你会发现WebView,WebViewCore等类在Java和C++部分都存在,它们是通过Java和c++一起实现的。
 
 

5.        Android Webkit插件

5.1.     本章的目的

       引导读者理解Android Webkit的插件框架, 通过介绍本人研究过程阅读过并认为有价值的文章,并对Android Framework源码中的SampleBrowserPlugin里难懂的地方进行解释, 希望能够清除读者对怎样写Android Webkit插件的疑惑。 SampleBrowserPlugin 是Android Webkit插件的例程, 位于源码中的development/samples/BrowserPlugin目录下, 先看一下里面的README文件吧。

5.2.     推荐先看几篇文章

l        https://developer.mozilla.org/en/Gecko_Plugin_API_Reference:虽然firefox是gecko的引擎,但是gecko和webkit的插件同样遵循NPAPI的标准, 这篇看完后就会弄如下几个问题:
(1)什么是Webkit插件, 有什么作用
(2)NPAPI一些函数和结构的作用。

l        http://www.zzzyk.com/kf/201203/123782.html:这篇文章会帮助你对Android Webkit插件有个简单的了解。

l       http://www.zzzyk.com/kf/201203/123783.html:这篇文章提到了Android Webkit插件的两种模式。

5.3.      架构

插件是用来扩展webkit的, 是webkit的智囊团。 例如有一种新类型的数据嵌在网页里,如下图所示, webkit不知如何处理, 此时webkit就会问他的插件们如何处理"application/x-shockwave-flash”类型的数据。


 
<embed src="http://player.youku.com/player.php/Type/Folder/Fid/13005645/Ob/1
补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,