Webkit for Android分析
来源:互联网 发布:猴王竞猜网站源码 编辑:程序博客网 时间:2024/05/20 06:24
目录(?)[-]
- 一、Android WebKit简介
- 二、Android WebKit模块框架
- Java层框架
- Java层源码说明
- Java层主要类关系图
- 流载入器(已废弃)
- C层框架
- C类与Java类的关系
- 三、基本流程分析
- webkit初始化
- JNI native方法注册
- UI线程和webcore线程
- 初始化过程序列图
- loadData
- loadData序列图
- webkit初始化
- Java层框架
网上有许多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所示:
图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块链表的处理2.1.2 Java层主要类关系图
WebKit Java层包含79个Java文件,主要的类关系图如下:
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层结构定义如下:
该结构作为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对象
- 调用System.loadLibrary载入webcore相关类库(C层)
- 如果是第一次初始化WebViewCore对象,创建WebCoreTherad线程
- 创建EventHub对象,处理WebViewCore事件
- 获取WebIconDatabase对象实例
- 向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 初始化过程序列图
3.2 loadData
loadData用于加载"data:”形式的url,通过该方法,可以将文件内容读入到字符串,然后通过loadData进行加载,是最简单的一种数据加载方法。比如:
webview.loadData(“<html><body>hello</body></html>”, "text/html”, "utf-8”);
3.2.1 loadData序列图
(未完待续)
http://mogoweb.net/categories/android-browser
- Webkit for Android分析
- Webkit for Android分析
- Webkit for Android分析
- Webkit for Android分析
- Webkit for Android分析
- Webkit for Android分析
- Webkit for Android分析
- Webkit for Android分析
- WebKit+分析–for+android
- WebKit 分析–for android
- WebKit 分析–for android
- WebKit 分析–for android
- WebKit 分析–for android
- WebKit 分析–for android
- WebKit 分析–for android
- WebKit 分析–for android
- WebKit 分析–for android
- WebKit 分析–for android【new】
- apache不解析php文档?提示需要下载
- 雁过也,月满西楼
- 【小技巧】ORA-12638: 身份证明检索失败解决方法
- 分享使用Box2D和Cocos2D制作弹球游戏的方法
- Domino控制台命令大全
- Webkit for Android分析
- Hive No partition predicate found for Alias xxx 解决方案
- 5个最好用的GIF制作软件
- DSP开发入门学习
- Android Spiner 添加与删除数据
- 写正确函数需要注意的地方:奇偶数分开,左边偶数,右边奇数。
- shell 调用函数 case
- dz 论坛x2.5爆路径 利用
- ld.so.1: test: fatal: libstdc++.so.6: open failed: No such file or directory.