Webkit for Android分析

来源:互联网 发布:猴王竞猜网站源码 编辑:程序博客网 时间:2024/05/20 06:24

目录(?)[-]

  1. 一、Android WebKit简介
  2. 二、Android WebKit模块框架
    1. Java层框架
      1. Java层源码说明
      2. Java层主要类关系图
      3. 流载入器(已废弃)
    2. C层框架
      1. C类与Java类的关系
    3. 三、基本流程分析
      1. webkit初始化
        1. JNI native方法注册
        2.   UI线程和webcore线程
        3. 初始化过程序列图
      2. loadData
        1. loadData序列图

网上有许多webkit的分析文章,其中针对android porting的一篇文章WebKit – WebKit For Android,写的非常好,分析得非常深入。不过这篇文章针对的Android版本比较老(具体版本无从考究),因此本文将在这篇文章的基础上,加入android 4.0 webkit porting的一些内容。

一、Android WebKit简介

Webkit是一个开源的浏览器排版和渲染引擎,包含WebCore和JavascriptCore。WebKit有众多的实现(Qt、Gtk, windows, chromium, android, etc)。Android 4.0平台的Web引擎框架采用了WebKit中的WebCore,javascript引擎则是采用google的V8引擎。Android 4.0的webkit采用了和chromium 12.0.742.130中webkit相同的codebase,webkit版本为534.30。

二、Android WebKit模块框架

Android平台的WebKit上层由Java语言封装,并且作为API提供给Android应用开发者,而底层使用WebKit核心库(WebCore)进行网页排版。WebKit模块分为两个部分: Java层和C层(webkit库)。Java层和C层通过JNI相互调用,如图1所示:

Java_CPP_Component_Diagram

图1 Android WebKit模块框架

一般而言,WebCore中回调Java的代码都位于Source/WebKit/下,但有一个例外,就是Source/WebCore/platform/android/GeolocationServiceBridge.cpp,该文件也包含回调到Java的代码。

2.1 Java层框架

2.1.1 Java层源码说明

Java层的代码位于frameworks/base/core/java/android/webkit目录下。各文件的简单说明如下:

AccessibilityInjector.java为WebView注入AccessibilityBrowserFrame.java对WebCore中Frame对象的Java层封装,用于创建WebCore中定义的Frame,以及为该Frame对象提供Java层回调方法ByteArrayBuilder.java辅助对象,用于byte块链表的处理CacheLoader.javaandroid 4.0 WebKit中不再使用CacheManager.javaCache管理对象,负责Java层Cache对象管理CallbackProxy.java该对象是用于处理WebCore与UI线程消息的代理类。当有Web事件产生时WebCore线程会调用该回调代理类,代理类会通过消息的方式通知UI线程,并且调用设置的客户对象的回调函数。CertTool.java证书工具ClientCertRequestHandler.java处理客户端证书请求ConsoleMessage.java来自WebCore的Javascript控制台消息ContentLoader.javaandroid 4.0 WebKit中不再使用CookieManager.java根据RFC2109规范,管理cookiesCookieSyncManager.javaCookies同步管理对象,该对象负责同步RAM和Flash之间的Cookies数据。实际的物理数据操作在基类WebSyncManager中完成。DataLoader.javaandroid 4.0 WebKit中不再使用DateSorter.java日期排序DebugFlags.java定义调试标志DeviceMotionAndroidOrientationManager.java用于实现DeviceMotion和DeviceOrientationDeviceMotionService.java实现SensorEventListener接口,处理动作DeviceOrientationService.java实现SensorEventListener接口,处理方向变化DownloadLister.java下载侦听器接口FileLoader.javaandroid 4.0 WebKit中不再使用FindActionModeCallback.java?FrameLoader.javaFrame载入器,用于载入网页Frame数据GeolocationPermission.java用于管理浏览器UI的位置信息权限GeolocationService.java实现java侧的GeolocationServiceAndroidHTML5Audio.javaHTML5 audio支持类HTML5VideoFullScreen.java全屏视频视图,仅提供给浏览器使用HTML5VideoInline.java内嵌视频视图,仅提供给浏览器使用HTML5VideoView.java视频视图,仅提供给浏览器使用HTML5VideoViewProxy.javaHTML5视频视图代理类HttpAuthHandler.javaHTTP认证请求,需要用户处理HttpAuthHandlerImpl.javaHttpAuthHandler实现,仅用于Android Java HTTP stackJniUtil.java供JNI使用的实用类,用于获取cache目录等C代码无法直接获取的信息,以及读取资源包中的文件等JsPromptResult.javaJs结果提示对象,用于向用户提示Javascript运行结果。JsResult.javaJs结果对象,用于用户交互JWebCoreJavaBridge.java用Java与WebCore库中Timer和Cookies对象交互的桥接代码。KeyStoreHandler.javahttps相关处理L10nUtils.java字符串国际化,在使用chrome http stack时用到LoadListener.java载入器侦听器,用于处理载入器侦听消息。MimeTypeMap.javaMIME类型映射MockGeolocation.java模拟地理位置信息Network.java该对象封装网络连接逻辑,为调用者提供更为高级的网络连接接口。OverScrollGlow.java?PerfChecker.java性能测试Plugin.java插件处理相关PluginData.java插件处理相关PluginFullScreenHolder.java插件处理相关PluginList.java插件处理相关PluginManager.java插件处理相关PluginStub.java插件处理相关SearchBox.java定义搜索对话框接口SearchBoxImpl.java搜索对话框接口实现SelectActionModeCallback.java?SslCertLookupTable.javahttps相关处理SslClientCertLookupTable.javahttps相关处理SslErrorHandler.javahttps相关处理SslErrorHandlerImpl.javahttps相关处理StreamLoader.javaandroid 4.0 WebKit中不再使用UrlInterceptHandler.java用于google gears,已废弃UrlInterceptRegistry.java用于google gears,已废弃URLUtil.javaURL处理实用类ValueCallback.java回调接口,用于异步返回数据值ViewManager.java子视图管理类,主要用于管理插件视图ViewStateSerializer.javaWebView视图序列化和反序列化WebBackForwardList.java该对象包含WebView对象中显示的历史数据。WebBackForwardListClient.java浏览历史处理的客户接口类,所有需要接收浏览历史改变的类都需要实现该接口。WebChromeClient.javaChrome客户基类,Chrome客户对象在浏览器文档标题、进度条、图标改变时候会得到通知。WebHistoryItem.java该对象用于保存一条网页历史数据WebIconDatabase.java图标数据库管理对象,所有的WebView均请求相同的图标数据库对象WebResourceResponse.java封装某个资源的响应信息WebSettings.javaWebView的管理设置数据,该对象数据是通过JNI接口从底层获取。WebStorage.java处理webstorage数据库WebSyncManager.java数据同步对象,用于RAM数据和FLASH数据的同步操作。WebTextView.java在html文本输入控件激活时,显示系统原生编辑组件WebView.javaWeb视图对象,用于基本的网页数据载入、显示等UI操作。WebViewClient.javaWeb视图客户对象,在Web视图中有事件产生时,该对象可以获得通知。WebViewCore.java该对象对WebCore库进行了封装,将UI线程中的数据请求发送给WebCore处理,并且通过CallbackProxy的方式,通过消息通知UI线程数据处理的结果。WebViewDatabase.java该对象使用SQLiteDatabase为WebCore模块提供数据存取操作。WebViewFragment.java实现WebView嵌入到Fragment中WebViewWorker.java实现html5 workers,在UI线程和webkit线程开启单独的线程ZoomControlBase.java缩放控件接口ZoomControlEmbedded.java内置缩放控件ZoomControlExternal.java扩展缩放控件,已废弃ZoomManager.java维护WebView的缩放状态
 
2.1.2 Java层主要类关系图

WebKit Java层包含79个Java文件,主要的类关系图如下:

Java layer class diagram

2.1.3 流载入器(已废弃)

在Android 4.0之前的版本,数据载入都是在Java层实现的,从4.0开始,Android webkit引入了chromium的部分代码,输入载入走的是C++代码。不过原有的Java代码仍然保留,可以在编译webkit时用USE_CHROME_NETWORK_STACK宏进行切换。

2.2 C层框架

2.2.1 C类与Java类的关系

1.BrowserFrame

与BrowserFrame Java类相对应的C++类为FrameBridge,该类为Dalvik虚拟机回调BrowserFrame类中定义的本地方法进行了封装。与BrowserFrame中回调函数(Java层)相对应的C层结构定义如下:

Image

该结构作为FrameBridge(C层)的一个成员变量(mJavaFrame),在FrameBridge构造函数中,用BrowserFrame(Java层)类的回调方法的偏移量初始化JavaBrowserFrame结构的各个域。初始后,当WebCore(C层)在剖析网页数据时,有Frame相关的资源改变,比如WEB页面的主题变化,则会通过mJavaFrame结构,调用指定BrowserFrame对象的相应方法,通知Java层处理。

2.JWebCoreJavaBridge

与该对象相对应的C层对象为JavaBridge,JavaBridge对象继承了TimerClient和CookieClient类,负责WebCore中的定时器和Cookie管理。与Java层JWebCoreJavaBridge类中方法偏移量相关的是JavaBridege中几个成员变量,在构造JavaBridge对象时,会初始化这些成员变量,之后有Timer或者Cookies事件产生,WebCore会通过这些ID值,回调对应JWebCoreJavaBridge的相应方法。

3.LoadListener

与该对象相关的C层结构是struct resourceloader_t,该结构保存了LoadListener对象ID、CancelMethod ID以及DownloadFiledMethod ID值。当有Cancel或者Download事件产生,WebCore会回调LoadListener类中的CancelMethod或者DownloadFileMethod。

4.WebViewCore

与WebViewCore相关的C类是WebCoreViewImpl,WebViewCoreImpl类有个JavaGlue对象作为成员变量,在构建WebCoreViewImpl对象时,用WebViewCore(Java层)中的方法ID值初始化该成员变量。并且会将构建的WebCoreViewImpl对象指针复制给WebViewCore(Java层)的mNativeClass,这样将WebViewCore(Java层)和WebViewCoreImple(C层)关联起来。

5.WebSettings

与WebSettings相关的C层结构是struct FieldIds,该结构保存了WebSettings类中定义的属性ID以及方法ID,在WebCore初始化时(WebViewCore的静态方法中使用System.loadLibrary载入)会设置这些方法和属性的ID值。

6.WebView

与WebView相关的C层类是WebViewNative,该类中的mJavaGlue中保存着WebView中定义的属性和方法ID,在WebViewNative构造方法中初始化,并且将构造的WebViewNative对象的指针,赋值给WebView类的mNativeClass变量,这样WebView和WebViewNative对象建立了关系。

三、基本流程分析

3.1 webkit初始化

Android提供了WebView类,该类提供客户化浏览显示的功能。如果客户需要加入浏览器的支持,可像使用其它视图类一样加入应用程序,显示给用户。当客户代码中第一次生成WebView对象时,会初始化WebKit库(包括Java层和C层两个部分),之后用户可以操作WebView对象完成网络或者本地资源的访问。

WebView对象的生成主要涉及4个类CallbackProxy、WebViewCore、WebViewDatabase以及BrowserFrame。其中CallbackProxy对象为WebKit模块中UI线程和WebKit类库提供交互功能,WebViewCore是WebKit的核心层,负责与C层交互以及WebKit模块C层类库初始化,WebViewDatabase为WebKit模块运行时缓存、cookie等数据存储提供支持,BrowserFrame用于创建WebCore中的Frame,并为Frame提供Java层回调方法。WebKit模块初始化流程如下:

实例化WebView

  • 创建CallbackProxy对象
  • 创建WebViewCore对象
    1. 调用System.loadLibrary载入webcore相关类库(C层)
    2. 如果是第一次初始化WebViewCore对象,创建WebCoreTherad线程
    3. 创建EventHub对象,处理WebViewCore事件
    4. 获取WebIconDatabase对象实例
    5. 向WebCoreThread发送初始化消息
      • 创建BrowserFrame对象
      • 向WebView发送WEBCORE_INTIALIZED_MSG_ID消息,通知初始化完成
  • 获取WebViewDatabase实例
  • 调用init初始化WebView
  • 收到WEBCORE_INITIALIZED_MSG_ID消息后,调用nativeCreate
3.1.1 JNI native方法注册

在创建WebViewCore时进行,调用System.loadLibrary方法载入webcore相关类库,该过程由Dalvik虚拟机完成,它会从动态链接库目录中寻找libWebCore.so类库,载入到内存中,并且调用WebKit初始化模块的JNI_OnLoad方法(代码见WebCoreJniOnLoad.cpp)。WebKit模块的JNI_OnLoad方法中完成了如下初始化操作:

1. 初始化JavaBridge[registerJavaBridge]

获取JWebCoreJavaBridge类的mNativeBridge成员变量的fieldID,以及注册JWebCoreJavaBridge类中的native方法

2. 初始化JniUtil[registerJniUtil]

注册JniUtil类中的native方法

3. 初始化WebFrame[registerWebFrame]

获取BrowserFrame类的mNativeFrame成员变量的ID,以及注册BrowserFrame类中的native方法

4. 初始化WebCoreResourceLoader[registerResourceLoader]

获取LoadListener类的mNativeLoader成员的ID,以及注册LoadListener类中的native方法

5. 初始化WebViewCore[registerWebViewCore]

获取WebViewCore类的java成员的ID,以及注册WebViewCore类中的native方法

6. 初始化WebHistory[registerWebHistory]

获取WebHistoryItem类的java成员的ID,以及注册WebBackForwardList和WebHistoryItem类中的native方法

7. 初始化WebIconDatabase[registerWebIconDatabase]

注册WebIconDatabase类中的native方法

8. 初始化WebSettings[registerWebSettings]

获取WebSettings类的java成员的ID,以及注册native方法

9. 初始化WebStorage[registerWebStorage]

注册WebStorage类的native方法

10. 初始化WebView[registerWebView]

获取WebView类的mNativeClass成员的ID,以及注册native方法

11. 初始化ViewStateSerializer[registerViewStateSerializer]

注册ViewStateSerializer类的native方法

12. 初始化GeolocationPermissions[registerGeolocationPermissions]

注册GeolocationPermissions类的native方法

13. 初始化MockGeolocation[registerMochGeolocation]

注册MockGeolocation类的native方法

14. 初始化HTML5Audio[registerMediaPlayerAudio]

注册HTML5 Audio类的native方法

15. 初始化HTML5Video[registerMediaPlayerVideo]

注册HTML5VideoViewProxy类的native方法

16. 初始化DeviceMotionAndOrientationManager[registerDeviceMotionAndOrientationManager]

注册DeviceMotionAndOrientationManager类的native方法

17. 初始化CookieManager[registerCookieManager]

注册CookieManager类的native方法

18. 初始化CacheManager[registerCacheManager]

注册CacheManager类的native方法

3.1.2  UI线程和webcore线程

webcore线程在第一次创建WebViewCore对象时创建, 且只创建一次,该线程负责处理WebCore初始化事件。WebViewCore构造函数会被阻塞,直到WebCoreThread初始化完成。在WebViewCore对象构造最后一步,发送INITIALIZE消息给WebCoreThread,执行webcore相关的初始化(WebViewCore::initialize)。在WebViewCore::initialize方法中,会创建BrowserFrame对象,并且向WebView对象发送WEBCORE_INITIALIZED_MSG_ID消息。WebView收到消息后,会执行nativeCreate方法,创建c层的WebView对象。

3.1.3 初始化过程序列图

Initialize Sequence

3.2 loadData

loadData用于加载"data:”形式的url,通过该方法,可以将文件内容读入到字符串,然后通过loadData进行加载,是最简单的一种数据加载方法。比如:

webview.loadData(“<html><body>hello</body></html>”, "text/html”, "utf-8”);

3.2.1 loadData序列图

LoadData Sequence

(未完待续)

 

 

http://mogoweb.net/categories/android-browser

原创粉丝点击