在手机操作系统中针对网页的浏览会封装一个webview类,这个类可以于窗口绑定,可以用来实现普通的窗口中浏览网页,而不用浏览器。只需要把webview的对象绑定到接口上就ok了。在webkit中有Page,Document和Frame等重要的类,Frame中包含一个DOMWindow的指针,用于显示该Frame的内容。所以,Frame和webview之间的关系是搞清楚这个普通窗口显示网页的关键。

在Android中,WebView类中有个WebViewCore的类,而就是WebViewCore类中包含了BrowserFrame的变量,该变量就是WebCore中的Frame类了。这样就基本上清楚了WebView和Frame之间的关系了。

由于没有读过Android的原代码,就结合另外一个操作系统来介绍一个loadUrl动作从WebView中怎样走到Frame中的吧。

WebView和WebViewCore中间辗转周折了好多层,但是总算是有联系的。在WebView的构造函数中会构造调用WebViewCore的构造函数。在WebViewCore的构造函数中会起一个WebCore线程,用于Frame的各种动作,WebView和WebCore::Frame之间是通过异步的消息机制通信的,他们是在不同的线程里。异步的消息机制用到的是Android的Looper-Handler机制。大致过程如下:

WebViewCore的构造函数-->起WebCore线程-->new一个Looper-->构造一个Handler-->while(1)的Loop()。这样就建立了一个线程,简单的运用了Looper-Handler异步消息机制。

Looper中含有一个MsgQueue,当Looper起来后,也构造这个MsgQueue,然后不停地发消息,其实调用的是Msg中指定的Handler中的对应HandleMessage函数。而Handler在构造的时候,Looper已经起来了,并且Handler是Looper的友类,Handler发送的消息都是发送到Handler中的MessageQueue中,而这个MessageQueue就是通过Looper::MyLooper()得到的。这样就完成了Handler发送消息到MessageQueue,而Looper不停地取消息然后调用消息对应的Handler中的HandleMessage函数。这样就有一个完整的消息机制了。

当WebCore线程起来后,会向这个Handler(在线程创建时create的)发WebViewCore的Init消息-->执行WebViewCore::Init的操作-->在Init中EventHub(也就是一个Handler)也会起来,也就是EventHub是在WebCore线程了-->EventHub中也包含了一个MessageQueue,和Looper中的MessageQueue是同一个。

这样一来就构成了WebView和Frame之间的联系,以loadUrl为例:

WebView::loadUrl

WebViewCore::sendMessage

EventHub::sendMessage

Looper::DispatchMessage

EventHandler::HandleMessage

BrowserFrame完成功能。

如何调用Message对应的Handler完成对应的功能(可以看到很多Message在send时指定的Handler都为NULL)?这里需要注意的是每个Handler在发送Message时都会把Target设置为自己。然后就走进了WevCore的世界了。

至此完毕了WebView到Frame之间的流程。