在Android 5.0系统中,文件WebView.java是一个内置的支持浏览器的视图View,此文件位于如下的目录中:
WebView作为应用程序的UI接口,为用户提供了一系列的网页浏览、用户交互接口,客户程序通过这些接口访问WebKit核心代码。WebView实现了WebKit的最核心功能。近年来随着用户对网络安全的重视,谷歌公司为了创建一个安全、稳定和快速的通用浏览器系统,特意推出了Chromium引擎驱动,这也是谷歌官方浏览器Chrome的引擎驱动。在全新的Android 5.0系统中,WebView将开始采用Chromium引擎驱动。
浏览Android 5.0源码时会发现,之前版本中的“external/WebKit”目录已经被移除掉,取而代之的是“chromium_org”。由此可见Chromium已经完全取代了之前的WebKit for Android。虽然Chromium完全取代了以前的WebKit for Android,但是Android WebView的API接口并没有变,与老的版本完全兼容。这样带来的好处是基于WebView构建的APP,无需做任何修改即可享受Chromium内核的高效与强大。
在Android 5.0系统中,“frameworks/base/core/java/android/webkit”目录下的各个文件如图7-2所示。
图7-2 “frameworks/base/core/java/android/webkit”目录下的文件
在Android 5.0中,设计者设计出了一个WebViewProvider接口,WebView本身并不实现具体的功能,而是将所有的处理功能交给WebViewProvider来实现。而WebViewProvider只是一个接口,至于具体的解决方案由实现者来决定到底采用哪一种引擎。其实从Android4.1系统开始就采用了这种架构模式,这说明谷歌那时便已经开始为以Chromium为驱动的WebView做准备。Android 5.0之前的版本,通过WebViewClassic实现WebViewProvider接口。Android 5.0系统中,则通过WebViewChromium实现WebViewProvider接口。
WebViewFactory也采用了相似的结构,设置了实例化WebViewFactoryProvider的具体策略。在WebViewFactoryProvider中有一个十分关键的接口createWebView,功能是创建具体的WebViewProvider。
Android 5.0中WebView的代码结构如图7-3所示。
由此可见,传统的基于AOSP master架构由WebKit实现的仍然保留,因为采用了灵活的架构,所以可以在AOSP和Chromium两种核心之间非常容易切换。
在Content API之上,Chromium的WebView实现封装了一个新的类AwContents,该类主要基于ContentViewCore类的实现,不同的是,AwContents需要基于一个原来存在于“chrome/”目录下的模块(图7-3中的Browser Components),但是AwContents不应该依赖该目录,所以,将Chrome中的一些功能实现模块化处理是Chromium的一个发展方向。目前,一些功能模块已经从Chrome中抽取出来了,具体请浏览“components/”。(www.xing528.com)
因为在AwContents中提供的不是WebView的API,所以需要借助中间桥接层,将AwContents桥接到WebView,这就是上图中的桥接模块,该模块位于Android 5.0源代码中的“frameworks/webview/chromium/java/com/android/webview/chromium/”目录下。类WebView Chromium和类WebViewChromiumFactory作为WebView的具体实现,需要依赖于Chromium项目的AwContents模块来实现。整体模块架构如图7-4所示。
图7-3 Android 5.0中WebView的代码结构
图7-4 AwContents模块的架构图
AwContents基于Content之上,专门针对WebView的需求进行封装,这个封装只是针对Android平台实现。同样道理,WebView也是基于Content API(Web Contents和ContentViewCore等)之上的,这一点它同Content Shell和Chromium浏览器没有大的不同,区别在于它们对很多Delegate类的实现不同,这是Content API用于让使用者参与内部逻辑和实现的过程。具体来说,主要有以下两个方面的不同。
(1)渲染机制
因为WebView提供的是一个View控件,所以View控件的容器可能会接受储存在CPU中的结构,例如bitmap,也可能是储存在GPU内存中的结构,例如surface,所以它需要提供两种不同的输出结果。
Chromium引入了一种新的合成器UberCompositor++,该合成器支持输出到GPU和CPU内存的两种方式。对于Compositor的结果输出到给定View的GPU内存的这种方式来说,关键点在于实现AwContents.InternalAccessDelegate接口的requestDrawGL方法。与requestDrawGL实现有关的代码不多,只有文件DrawGLFunctor.java和文件GraphicsUtils.java,还有与之关联的本地实现文件draw_gl_functor.cpp、raphic_buffer_impl.cpp和graphics_utils.cpp,本地代码位于“frameworks/webview/chromium/plat_support”目录下,此部分并不仅使用了Android SDK和NDK的API,而且也涉及到了Android源码。
(2)进程
目前WebView只支持单进程,未来版本应该支持多进程方式。单进程意味着没有办法使用Android的isolated UID机制,因此,某种程度上来讲,安全性降低了,而且页面的渲染崩溃会导致使用WebView的应用程序崩溃。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。