转载请注明原文地址:http://blog.csdn.net/milado_nju

## 概述

相信读者已经注意到了,在最新的Android 4.4 Kitkat版本中,原本基于Android WebKit的WebView实现被换成基于Chromium的WebView实现。在前面的章节中,笔者也介绍过基于Chromium的WebView实现即将成为Android系统上的缺省实现方式,笔者也一直期待这一重大转变,现在它真的发生了。而之前基于WebView接口的应用程序甚至可以直接工作在该实现上而不需要任何特别的改变。举个例子来说,Android系统上的缺省浏览器(AOSP中的浏览器),可以不需要任何改变直接工作在新的实现上。

WebView是一种嵌入式的编程接口,能够提供Java接口给开发者来使用该模块来渲染网页。现在的WebView只是一个接口类,通过一些内部设计的改变,其具体的实现可以在之前的Android WebKit和Chromium之间进行切换。新的Chromium实现专注于提供一致性的接口(为了兼容以前的应用),而内部的渲染引擎改为使用基于Blink/Content内核的引擎,这实现不管是从功能上还是性能来讲,都带来巨大的提升。为了支持WebView的工作方式,Chromium还是做了不少的改变的,例如前面提到的进程模型,渲染方式等,下面一一对他们作介绍。

## 层次结构

在Android 4.4中,基于Chromium项目的WebView千呼万唤始出来。为了支持历史遗留的接口,Chromium还是做了很大改变的,让笔者结合下图的层次结构来解释基本的过程。

上图主要有四个部分,其中跟WebView相关的主要是上面三个部分,首先是WebView接口部分,它提供对外编程接口,同时它的内部实现可以基于桥接代码,也就是第二个部分。桥接部分的代码主要有两个作用,其一是实现WebView接口对实现的调用,第二是调用下面一层的代码,这里面有个重要的部分就是需要设置AwContents为了绘图而需要设置的两组函数数组,这个在渲染部分介绍。它的代码可以在frameworks/webview/chromium部分找到。以上两个部分都是AOSP部分代码,而第三个部分是AwContents是在Chromium项目中的,主要是构建被桥接代码使用的接口,这一部分主要基于Content接口,里面有很多不同于Chrome浏览器的实现。Android的开源代码为了编译上的方面,直接将Chromium 版本30代码包含到external/chromium_org目录中,有兴趣的读者可以自行查看。

## 同Chrome浏览器的比较

同Chrome浏览器比较,Chromium WebView在很多部分非常不一样,例如开源与否、HTML5功能、版本支持、进程模型、渲染方式等。下表分析了这二者的主要区别。

Chromium WebView

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

理解WebKit和Chromium: Android 4.4 上的Chromium WebView的更多相关文章

  1. 理解WebKit和Chromium(电子书)

    前言   基础篇 WebKit, WebKit2, Chromium和Chrome介绍 WebKit和Blink WebKit和Chromium代码目录结构介绍 WebKit和Chromium功能模块 ...

  2. 理解WebKit和Chromium: 调试Android系统上的Chromium

    转载请注明原文地址:http://blog.csdn.net/milado_nju 1. Android上的调试技术 在Android系统上,开发人员能够使用两种不同的语言来开发应用程序,一种是Jav ...

  3. 理解WebKit和Chromium: 硬件加速之RenderLayer树到合成树

    转载请注明原文地址:http://blog.csdn.net/milado_nju ## 概述 在前面的章节中,笔者介绍了WebKit渲染引擎是如何有HTML网页构建DOM树.RenderObject ...

  4. Ubuntu18.04上使用LLDB调试Chromium Android C++代码。

    ###动机###Chromium Android源代码庞大且复杂.在调试器LLDB下能帮助我们更好的理解代码流程.介绍使用LLDB调试器调试android上chromium的C++代码. [1] 编译 ...

  5. 理解WebKit和Chromium: Chromium WebView和Chrome浏览器渲染机制

    转载请注明原文地址:http://blog.csdn.net/milado_nju ## 数据对比 前面介绍过Chromium WebView的时候,说过有关ChromiumWebView同Chrom ...

  6. 理解WebKit和Chromium: Chromium插件和扩展基础

    转载请注明原文地址:http://blog.csdn.net/milado_nju ##概述 插件和扩展是一种扩充浏览器功能的技术,在之前我们介绍过NPAPI插件技术,在Chromium中,远远不只是 ...

  7. 理解WebKit和Chromium:Chromium资源磁盘缓存

    转载请注明原文地址:http://blog.csdn.net/milado_nju ## 概述 想象一下,如果没有磁盘缓存的世界.当用户访问网页的时候,每次浏览器都需要从网站下载网页,图片,JS等资源 ...

  8. LINUX上使用GDB单步调试Chromium Android C++代码。

    ###动机###在LINUX使用GDB单步调试Chromium Android C++代码. [1]编译android平台Chromium, 修改GN文件中编译选项:-g -O0 使得编译优化更少,便 ...

  9. 开源框架】Android之史上最全最简单最有用的第三方开源库收集整理,有助于快速开发

    [原][开源框架]Android之史上最全最简单最有用的第三方开源库收集整理,有助于快速开发,欢迎各位... 时间 2015-01-05 10:08:18 我是程序猿,我为自己代言 原文  http: ...

随机推荐

  1. CSS布局套路

    这篇笔记的目的是记录分别应用float和flex布局的方法.主要是对遇到的问题进行总结. 1.float布局 总结: 1.1 使用float布局要清除浮动,清除的方法是,在父元素添加如下样式 .cle ...

  2. MLDS笔记:Optimization

    当函数空间覆盖到目标函数时,如何通过优化调整神经网络的参数找到这个目标函数呢? 深度学习中的损失函数是非凸的,非凸优化是个NP-hard问题,如何通过梯度下降来解决这个问题呢? 注意,不同于learn ...

  3. SpringBatch前言

    批处理应用程序就是对程序进行批量处理. 特点:批量应用程序处理大量数据而无需人类干预. 用途:可以选择使用批处理程序来计算每月的财务报表.计算统计和索引文件的数据等等. 应用:当银行系统中有很多业务都 ...

  4. Java中常用缓存Cache机制的实现

    缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例. 这样做可以减少系统开销,提高系统效率. 缓存主要可分为二大类: 一.通过文件缓存,顾名思义文件 ...

  5. hadoop入门级总结二:Map/Reduce

    在上一篇博客:hadoop入门级总结一:HDFS中,简单的介绍了hadoop分布式文件系统HDFS的整体框架及文件写入读出机制.接下来,简要的总结一下hadoop的另外一大关键技术之一分布式计算框架: ...

  6. android 自定义ViewGroup之浪漫求婚

    *本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 1.最终效果 有木有发现还是很小清新的感觉 2.看整体效果这是一个scrollView,滑动时每个子view都有一个或多个动画效果 ...

  7. Android自定义View(LineBreakLayout-自动换行的标签容器)

      最近一段时间比较忙,都没有时间更新博客,今天公司的事情忙完得空,继续为我的自定义控件系列博客添砖加瓦.本篇博客讲解的是标签自动换行的布局容器,正好前一阵子有个项目中需要,想了想没什么难度就自己弄了 ...

  8. 理解性能的奥秘——应用程序中慢,SSMS中快(4)——收集解决参数嗅探问题的信息

    本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 接上文:理解性能的奥秘--应用程序中慢,SSMS中快(3)--不总是参数嗅探的错 前面已经提到过关于存储过程在SSMS中运行很 ...

  9. 用scheme重写Python的三大函数map reduce 和filter

    重写过程中,发现这种做法能加深对递归的理解,而且reduce还体现了函数式编程是如何通过参数传递来实现命令式编程中的状态改变的. (define (imap f x . y) (if (null? y ...

  10. [Pelican]Pelican入门(二)

    之前是搭建了一个简单的博客,但是没有图片,没有具体的栏目分类 这次来研究下 一 导航栏 之前是直接把.md扔到的content文件夹下,结果导航栏,显示的是Category信息. 现在这么改成 D:. ...