转载请注明原文地址:http://blog.csdn.net/milado_nju
html
## 概述android
相信读者已经注意到了,在最新的Android 4.4 Kitkat版本中,本来基于Android WebKit的WebView实现被换成基于Chromium的WebView实现。在前面的章节中,笔者也介绍过基于Chromium的WebView实现即将成为Android系统上的缺省实现方式,笔者也一直期待这一重大转变,如今它真的发生了。而以前基于WebView接口的应用程序甚至能够直接工做在该实现上而不须要任何特别的改变。举个例子来讲,Android系统上的缺省浏览器(AOSP中的浏览器),能够不须要任何改变直接工做在新的实现上。web
WebView是一种嵌入式的编程接口,可以提供Java接口给开发者来使用该模块来渲染网页。如今的WebView只是一个接口类,经过一些内部设计的改变,其具体的实现能够在以前的Android WebKit和Chromium之间进行切换。新的Chromium实现专一于提供一致性的接口(为了兼容之前的应用),而内部的渲染引擎改成使用基于Blink/Content内核的引擎,这实现不论是从功能上仍是性能来说,都带来巨大的提高。为了支持WebView的工做方式,Chromium仍是作了很多的改变的,例如前面提到的进程模型,渲染方式等,下面一一对他们做介绍。chrome
## 层次结构编程
在Android 4.4中,基于Chromium项目的WebView千呼万唤始出来。为了支持历史遗留的接口,Chromium仍是作了很大改变的,让笔者结合下图的层次结构来解释基本的过程。canvas
上图主要有四个部分,其中跟WebView相关的主要是上面三个部分,首先是WebView接口部分,它提供对外编程接口,同时它的内部实现能够基于桥接代码,也就是第二个部分。桥接部分的代码主要有两个做用,其一是实现WebView接口对实现的调用,第二是调用下面一层的代码,这里面有个重要的部分就是须要设置AwContents为了绘图而须要设置的两组函数数组,这个在渲染部分介绍。它的代码能够在frameworks/webview/chromium部分找到。以上两个部分都是AOSP部分代码,而第三个部分是AwContents是在Chromium项目中的,主要是构建被桥接代码使用的接口,这一部分主要基于Content接口,里面有不少不一样于Chrome浏览器的实现。Android的开源代码为了编译上的方面,直接将Chromium 版本30代码包含到external/chromium_org目录中,有兴趣的读者能够自行查看。数组
## 同Chrome浏览器的比较浏览器
同Chrome浏览器比较,Chromium WebView在不少部分很是不同,例如开源与否、HTML5功能、版本支持、进程模型、渲染方式等。下表分析了这两者的主要区别。安全
|
Chromium WebViewide |
Chrome浏览器(Android版) |
是否开源 |
所有开源,包括内核,桥接层等 |
Java层部分的代码,包括用户界面的代码是闭源的,也就是说开发者是没有办法基于Chrome浏览器定制新浏览器,只能够基于Content层 |
HTML5功能 |
目前不支持WebGL,WebRTC,WebAudio等 |
支持绝大多数HTML5功能(HTML5test得分超过450),包括WebGL,WebRTC,WebAudio等 |
版本 |
仅能工做在Android4.4上,并且依赖于系统内部的函数,只能同Android AOSP一块儿编译,目前是Chromium 30的版本 |
能工做在>=Android 4.0,并且不须要依赖Android系统内部的函数。Chromium方面是跟随最新的代码。 |
进程模型 |
仅单进程 |
支持多进程和单进程(不过,目前单进程工做还有些问题) |
渲染方式 |
支持软件渲染和硬件加速渲染方式 |
目前只是硬件加速渲染方式 |
## 渲染方式
至于WebView内部所使用的Chromium实现是采用硬件加速渲染仍是软件渲染,这里仍是比较复杂的。根据Android的View结构,WebView的内容须要经过一个onDraw(Canvas c)来完成绘制。为了将Chromium渲染网页的结果绘制到该Canvas中,须要两组绘图函数组,第一组用来软件渲染,第二组用来硬件加速渲染。而这两组函数须要使用Android内部函数,这决定了目前WebView只能同Android AOSP代码一块儿编译,而不能像应用程序同样,只是依赖于Android SDK/NDK来编译。下图是当用户界面或者网页须要绘制的时候,绘图的基本过程。
这里Chromium的合成器具备两种能力,就是包含支持软件渲染的软件渲染器和硬件加速渲染的渲染器。当用户界面所对应的画布(canvas)是硬件加速的话,那么内部采用硬件渲染机制。若是不是硬件加速的话,那么采用软件渲染机制。当用户的界面设置为硬件加速的时候(开发者能够在应用程序的AndroidManifest.xml中设置属性android:hardwareAccelerated="true"),那么用户界面对应的画布即为硬件加速,不然即为软件渲染方式。因此,具体Chromium WebView采用什么样的方式,取决于调用WebView的应用程序的设置方式。
值得提出的是,这里的硬件加速机制同Chrome浏览器的硬件加速机制是不一致的,由于Chrome浏览器为渲染网页使用的控件是Android的SurfaceView,根据Android系统的说明,SurfaceView是能够在不一样的线程来绘制的(One of the purposes of this class is to provide a surface in which a secondary thread can render into the screen),请读者阅读这里了解背后的原理http://developer.android.com/reference/android/view/SurfaceView.html。由此,Chrome浏览器是首先获取SurfaceView的Surface对象的句柄(ID),而后由Chrome浏览器的GPU线程来绘制网页。这样,网页的渲染工做同主线程彻底隔离开来了,不会由于网页的渲染而阻碍用户界面的响应。
而在Chromium WebView的实现中,由于WebView不是基于SurfaceView类的(由于历史遗留问题),因此,绘制内容到画布上必须在主线程来操做,有鉴于此,这些渲染任务只能在主线程上工做,可能在某种程度上会阻碍用户界面的响应,这是一个重大缺陷。根据笔者的数据来看,目前它的性能同Chrome浏览器/Content Shell也有必定的差距,考虑使用它的读者可能须要权衡一下。
由于WebView采用单进程的渲染方式并省略了一些共享内存和进程间通讯的基础设备,因此能够节省一些内存使用空间,Chromium的官方也给出了一些数据,例如打开一个空白页,WebView目前只是须要33MB内存,而Chrome浏览器须要大概49MB,而单进程模式的Chrome浏览器须要大概45MB内存,还有更多详细的数据,有兴趣的读者能够进行参考和一些分析。
## 基于WebView的浏览器和基于Content接口的浏览器
目前Android默认浏览器(Stock Browser)是基于WebView接口,由于ChromiumWebView的实现被直接用于默认浏览器中,因此继承了ChromiumWebView的一些缺点,例如多标签页也只是在同一进程中工做,没有沙箱模型的支持等,性能也要差很多。而Chrome浏览器的Android版是基于Content接口的多进程方式工做的,于是保留了稳定性好,安全等好处。
## 参考资料
1. https://developers.google.com/chrome/mobile/docs/webview/overview
2. https://android.googlesource.com/platform/external/chromium_org/
by yongsheng@chromium.org