分类目录归档:chromium研究

在本地服务器上建立chromium镜像

Android 5.0发布了好长时间,一直都没有来得及研究。前两周终于将android 5.0源码下载了下来,大致看了一下代码。我所关注的并非Material Design,而是Android 5.0的web引擎。从Android 4.4开始,采用了chromium/blink内核,Android 5.0自然也不例外,只是chromium的版本升级到了37.0.2062.116。想到我的chromium webview项目,仍然采用的是34.0.1847,因此打算也将chromium版本进行一次升级。

因为可恶的GFW,下载代码及其不顺利,虽然有VPN,但是对于几十G的chromium下载量,下载速度太慢,而且git不支持断点续传。在折腾了两三个星期之后,决定在公司的服务器上建立chromium的镜像。不知道从哪个版本开始,gclient开始全面转向git。由于git的天然的分布式特点,这为完全镜像chromium源码库提供了便利。

chromium源码库是由chromium本身加上一堆第三方开源库组成,极其庞大。为此我写了一个脚本,放到了github上,有兴趣的可以访问chromium_mirror_script项目,其中chromium_git_list.txt为所有的源码库列表,来自https://chromium.googlesource.com/,随着时间的推移,这个列表也可能发生变化。

有了内部的chromium镜像后,我们可以修改.DEPS.git文件,将其中的git_url值替换为本地git地址,这样通过gclient下载,就是从本地镜像服务器上获取代码了。

Chromium网络加载速度研究(1)

本文主要内容翻译自Google的文档Data Compression Proxy,如果您觉得文章写的不明白,请参看原文。

对于一款浏览器而言,速度无疑是非常重要的,其中加载速度更是重中之重。UC浏览器很早就采用了云端加速技术,所以在网页加载速度方面一直很有优势。现在越来越多的浏览器,如Opera、QQ浏览器都采用了服务器端加速技术。Chrome移动版从V33开始正式支持数据压缩代理。下面就分析一下Chrome for Android所采用的数据压缩技术。

数据压缩代理

最新的Chrome for Android支持数据压缩代理,通过Google部署的代理服务器优化网站内容,可以极大的减少数据流量。有数据表明,采用这一特性可以减少web页面大小的50%。要启用这一功能,进入Chrome浏览器的菜单"设置->带宽管理->减少数据流量消耗",然后打开即可。

实现原理

最核心的优化,减少数据大小,是由Google服务器实现的。当开启了"数据压缩代理"特性时,Chrome在手机和运行于Google数据中心的服务器之间建立连接,所有非加密的HTTP请求都通过该连接中转。

Data Compression Proxy

代理服务器收到手机发起的请求后,向目标网站发起请求,对每个回应进行优化,再回给手机。内容优化是通过Google的开源库PageSpeed实现的,该库针对Chrome移动浏览器进行了特别的微调。网页的渲染、JavaScript执行,是由手机上的Chrome浏览器完成的。

  • HTTPS连接不通过数据压缩代理
  • 使用数据压缩代理不需要Google账号
  • 匿名窗口中的浏览不经过数据压缩代理

如果您对压缩代理节省的带宽表示怀疑,可以进入到浏览器设置中查看浏览器接收数据的原始大小和优化大小的对比图。如下图所示,带宽节省增长很快。

bandwidth usage

让我们近距离观察一下压缩代理进行了那些特别的优化。

SPDY

从手机到代理服务器会尽力采用SPDY, 这是一个针对Web优化的协议,得到了Chrome/Firefox和Opera的支持,也是即将到来的HTTP/2.0标准的基础。如果SPDY连接无法创建,则会建立一个普通的HTTP/1.1代理连接。

http-https

使用SPDY协议,代理服务器可以在一个TCP连接上同时复用多个请求和回应,这样做有很大的好处:它可以分摊多个请求的TCP握手开销。去掉每个请求的TCP慢速启动阶段,提高吞吐量,还能在数据流上智能的定义请求和回应优先级。事实上,研究表明仅仅使用SPDY可以减少移动网络下23%的页面加载时间,这还没有将内容优化算在内。

此外,使用数据压缩代理还有许多其它的好处:

  • DNS延迟绑定:DNS查找由代理服务器执行,而不是由手机,这样查找过程可以快很多。
  • 更少的网络活动和更快的加载速度意味着移动射频活动期更短(减少电量消耗)
内容优化

悲剧的是,大多数网站并没有对移动终端进行优化,导致内容加载低效和渲染慢。PageSpeed的经验表明,许多内容的优化可以自动完成,就如同数据压缩代理所做的。

图片转码: 平均下来,每个页面60%的传输数据是图片。为此,代理服务器特别对此进行优化,将所有的图片都转码为WebP格式。WebP比当前流行的格式,如JPEG和PNG,数据量更小。代理支持最新的WebP无损格式,并根据设备分辨率和像素密度对每个图像进行优化。综合各种方法,图像大小可以减少80%。

内容压缩: 代理智能的压缩和缩减HTML、JavaScript和CSS资源,通过移除不必要的空格、注释以及其它与页面渲染无关的元数据,再加上对所有资源启用gzip压缩,可以极大的节约带宽。

安全浏览: 代理实现了移动Chrome浏览器上的安全浏览,当您访问恶意或者钓鱼网站时会告之浏览器,浏览器会显示一个警告页面。恶意网站列表由代理持续更新。

该采用云加速技术吗?

通过前面的分析,采用数据压缩代理似乎是个不错的方案,但是从图1可以看出,所有的数据都需要通过数据压缩代理中转,这就要求:

  • 拥有强大的服务器,快速的进行数据压缩
  • 拥有强大的数据中心,否则瓶颈会存在于数据压缩代理
  • 拥有强大的分布式计算能力,浏览器终端需要能够就近连接数据压缩代理

在中国,Chrome for Android如果开启数据压缩代理功能,速度反而更慢,其原因就在于Google在中国并没有部署服务器。对于个人开发者和中小企业,一来无法部署强大的数据中心,二来也无法使用Google的服务,所以服务器端加速方案不具备可行性。

基于chromium的产品开发的源码管理策略

chromium这个开源项目的特点之一就是代码量庞大,使用了众多的第三方开源库,整个版本库差不多10G了。特点之二就是更新频繁,
去年chrome的版本还是v16,现在chrome已经更新到v32了。所以有时基于chromium开发浏览器非常痛苦,一不小心就落后别人一大截。源码管理是项目启动之初就需要考虑的,在这方面我们就走了弯路,下面就分析一下源码管理策略,至于采用何种策略就需要根据项目需求和环境而定。

Android 4.4 WebView实现分析

随着Android4.4的发布,Android WebView改成由Chromium驱动了。浏览Android4.4源代码,可以看到之前版本中的external/WebKit目录被移除掉了,取而代之的是chromium_org。也就是说chromium已经完全取代了之前的WebKit for Android。虽然chromium完全取代了以前的WebKit for Android,但Android WebView的API接口并没有变,与老的版本完全兼容。这样带来的好处是基于WebView构建的APP,无需做任何修改,就能享受chromium内核的高效与强大。下面就Android 4.4中WebView的实现进行分析。

先来看看frameworks/base/core/java/android/webkit下的文件,里面有我们熟悉的WebView、WebSettings、WebViewClient等类,其中最主要的就是WebView了,相关的类关系如下:

wps_clip_image-510

    从图中可以看出,设计者抽象出了一个WebViewProvider接口,WebView本身并不做事,所有的处理就是交给WebViewProvider。而WebViewProvider只是一个接口,由实现者决定采用哪种引擎。从Android4.1开始,就采用了这种设计架构,开始为chromium核心的WebView做准备。在Android 4.4之前的版本,由WebViewClassic实现WebViewProvider接口。在Android4.4中,则是WebViewChromium实现WebViewProvider接口。WebViewFactory也采用了相似的结构,决定了如何实例化WebViewFactoryProvider,WebViewFactoryProvider有一个关键的接口createWebView,创建具体的WebViewProvider。(注:AOSP master源码基于WebKit的实现仍然保留,但在Android4.4中已经移除,由于采用了灵活的架构,所以在两种核心之间非常容易切换)

目前的代码结构如下图所示,在ContentAPI之上,Chromium的WebView实现封装了一个新的类AwContents,该类主要基于ContentViewCore类的实现,不同的是,AwContents需要基于一个原来存在于“chrome/”目录下的模块(图中的BrowserComponents),但是AwContents不应该依赖该目录,所以,将chrome中的一些所谓的浏览器模块化是Chromium的一个方向。目前,一些模块以及从chrome中抽取出来了,参见“components/”。

wps_clip_image-31344

AwContents提供的不是WebView的API,所以,需要一层桥接部分,将AwContents桥接到WebView,这就是图中的桥接模块,该模块位于Android源代码中的frameworks/webview/chromium/java/com/android/webview/chromium/目录下,WebViewChromium和WebViewChromiumFactory类作为WebView的具体实现,依赖于Chromium项目的AwContents模块,整体模块图如下:

wps_clip_image-26071

AwContents基于Content之上,专门针对Android WebView需求而进行的一个封装,这个封装只针对Android平台。

WebView同样也是基于ContentAPI(web contents, ContentViewCore等),在这点上来说,它同Content Shell和Chromium浏览器没有大的不同,区别在于它们对很多Delegate类的实现不同,这是ContentAPI用于让使用者参与内部逻辑和实现的过程。具体来说,它主要有以下两个方面的不同:

1.   渲染机制

因为WebView提供的是一个View控件,那么View控件的容器可能接受储存在CPU中的结构(如bitmap),也可能是储存在GPU内存中的结构(如surface),所以它需要提供两种不同的输出结果。

Chromium引入了一种新的合成器UberCompositor++,该合成器支持输出到GPU和CPU内存两种方式。对于Compositor的结果输出到给定View的GPU内存这种方式,关键点在于实现AwContents.InternalAccessDelegate接口的requestDrawGL方法。与requestDrawGL实现有关的代码不多,只涉及到DrawGLFunctor.java和GraphicsUtils.java,以及与之关联的native实现draw_gl_functor.cpp, graphic_buffer_impl.cpp和graphics_utils.cpp,naitve代码位于frameworks/webview/chromium/plat_support目录下。这部分代码不多,但牵涉到了Android源码,并不是只使用了Android SDK和NDK的API。

2.   进程

目前WebView只支持单进程方式,未来不排除支持多进程方式。单进程意味了没有办法使用Android的isolated UID机制,因此,某种程度上来讲,安全性降低了,而且页面的渲染崩溃会导致使用WebView的应用程序崩溃。

Android 4.4中的chromium

Android 4.4代码树中的chromium源码位于external/chromium_org,而不是external/chromium, external/chromium是一个老版本的chromium,主要提供chromium net网络栈。external/chromium_org下的chromium版本为r227252,对应的Chromium发行版本为30.0.1599.101, Blink版本为r159105。

AOSP源码中的默认浏览器基于chromium核心,但Browser代码和之前的版本并没有差别,这也看出WebView API的兼容性相当好。而google官方则宣布以后android系统中不再提供浏览器,只有Chrome for Android。

Android4.4中的chromium移植分析

从Android4.4的chromium_org git库log可以看到,从chromium源码获取分支后,只cherry-pick了两个提交,而且cherry-pick的代码也是来自chromium项目,信息如下:

commit 3311b27cb6fdbe7af035a7d769944a17328c6227

Author: Ben Murdoch <benm@google.com>

Date:   Mon Oct 21 12:33:52 2013 +0100

    Cherry pick  [Android] MediaPlayerBridge should pass Bridge to getAllowedOperations

    Cherry pick of https://codereview.chromium.org/32213003/

    Bug: 11311417

    Original description:

    [Android] MediaPlayerBridge should pass Bridge to getAllowedOperations

    Right now the Java side is expecting a MediaPlayer object to be passed

    to the MediaPlayerBridge.getAllowedOperations function, but native

    is actually passing it a MediaPlayerBridge. Update the code to be

    consistent - Java now expects the MediaPlayerBrdige and uses it to

    extract a MediaPlayer.

    Change-Id: I5ac618c833c6c3ff015d43405a9a4d507fce9ba5

commit 41a8683eef4139670e32f284a160dc3702d9a5c2

Author: Ben Murdoch <benm@google.com>

Date:   Mon Oct 21 11:04:45 2013 +0100

    Cherry pick android: fix base::Time::FromLocalExploded() crash.

    Cherry pick of https://codereview.chromium.org/27472003/

    Bug: 11313033

    Original description:

    android: fix base::Time::FromLocalExploded() crash.

…skipping…

    Record Chromium merge at DEPS revision 30.0.1599.101

    This commit was generated by merge_to_master.py.

    Change-Id: Ie9e9e034f3e5d9a3fe3edf87595c7be467d3136b

结合前面的分析,可以得出如下结论:

1)AwContents都是基于Android SDK/NDK开发,并没有使用Android Source里面的未公开API和库。

2)Android 4.4中使用的chromium,直接取自chromium开源项目,虽然它使用了自己的git库:https://android.googlesource.com/platform/external/chromium_org

3)Android4.4中的chromium并没有针对android平台做一些特殊修改,和chromium开源项目的代码一致

4)与Android source密切相关的代码位于ChromiumWebView。如前面所述,在实现reqeustDrawGL时,使用到了Frameworks 未公开的API,native部分代码也用到了Android source中的代码。所涉及的类和Android Source如下:

1.HardwareCanvas

2.ViewRootImpl

3.DrawGlInfo.h

4.GraphicBuffer.h

5.GraphicsJNI.h

5)整个chromium移植代码中,与android source密切相关的代码极少,绝大部分都是基于SDK和NDK而开发。

调试ContentShell启动过程的方法

本文探讨的如何调试ContentShell for Android的启动过程,主要是C++部分代码的流程,这对于理解ContentShell的启动流程、render进程是如何创建并启动的有很大的帮助。

理解Contenthell启动流程的最好方法是使用调试器逐步跟踪,不过chromium在很多地方采用了异步方式,单步跟踪相当困难,比较好的方法是在关键代码处打上断点,查看调用栈。由于ContentShell程序一启动,就会执行启动流程,启动主进程和render进程,并加载网页,这时再用gdb attach到进程,往往我们希望跟踪的代码已经执行过去了。一种比较土的方法就是在程序入口处加上sleep语句,在程序暂停时,执行gdb attach到进程,然后在关键代码处设上断点。这种方法有点不好的地方就是sleep的时间不好定,定短了,gdb还没有attach上去,程序已经执行过了。设长了,每次等的时间就长了。

其实chromium开发者已经考虑到这种需求,所以加入了一个命令行参数:wait-for-java-debugger。查看代码,可以发现在ContentShellActivity.java中就有一个方法waitForDebuggerIfNeeded(),其作用就是等待java调试器attach之后才继续往下执行。所以本文介绍的方法就是jdb/gdb组合来调试ContentShell启动过程。

  1. 修改content/shell/android/shell_apk/AndroidManifest.xml,在application节点加入android:debuggable=”true”,然后编译ContentShell,安装到连接的android设备。
  2. 从这里下载jdb_content_shell脚本,放到build/android目录下。
  3. 执行如下命令增加命令行参数:
    adb_content_shell_command_line --wait-for-java-debugger
  4. 启动android设备上的ContentShell。应该可以看到界面只是一个空白界面,程序没有接着往下执行。
  5. 执行adb_gdb_content_shell命令启动gdb调试,设置断点。
  6. 执行jdb_content_shell命令,可以观察到程序在继续往后执行。

[译]Android WebView

原文地址:https://crosswalk-project.org/#wiki/android-webview

1. 架构&组件

  • AOSP中的Android WebView将基于AwContents,其位于Content API和Content View之上。
  • 与Content API不同,它还依赖于从最初的chrome browser分离出来的组件,组件位于components/下,包含auto_login_parser,navigation_interception,visitedlink_browser,visitedlink_renderer和web_contents_delegate_android,这些都是用于页面。
  • 无渲染进程(进程内渲染),无沙盒机制(sandbox机制)
  • 图形架构和Content Shell有很大的不同,且正在开发中,将支持软件和硬件输出。

2. API

  • API类似于EFL WebView,不会暴露内部的browser/renderer/gpu进程。
  • 能够加载URL,接收加载过程中的事件和回调。
  • 可通过addJavaScriptInterface扩展JavaScript API,允许JavaScript调用Java代码,反之这不支持。
  • 提供了若干API接收页面状态改变通知和页面回调。

3. 消息循环和事件处理

  • 整合利用Android消息处理
  • native代码设置定时器到Java侧的消息循环

4. 图形

  • 渲染使用chromium合成器,开启了硬件加速
  • 合成器输出支持软件和硬件Surface
  • 硬件加速的架构和content shell不同,和ChromeOS类似。现在还处在早期开发阶段,使用了UberCompositor,支持软件输出

5. WebAPI扩展

  • API addJavaScriptInterface可用于JavaScript API扩展,但支持JavaScript调用Java代码。
  • 相反方向的调用(Java -> JavaScript)不支持
  • addJavaScriptInterface通过NPObject机制(之前用于NPAPI插件)支持进程外访问,虽然在WebView中不再需要。
  • 来自Java侧的事件通知貌似还不支持

6. API细节和涵盖范围

  • WebViewClient用于页面状态改变通知
  • WebChromeClient包含参与渲染逻辑的回调
  • 原生代码/JS交互
  • 页面加载
  • 导航&历史记录
  • 文字搜索
  • 事件处理
  • 轨迹球、触摸、键盘
  • 不支持鼠标事件
  • 设置:编码
  • 页面信息:标题、favicon
  • HTTPS/SSL
  • 页面加载状态、缩放、重定向、URL重载,等等

7. 源码

  • src/android_webview
    • android_webview_java.jar, libwebviewchromium.so和webviewchromium.pak是本模块的编译目标.
  • Google的工程师正在Android开源项目里开发基于Chrome核心的新WebView.
    • 官方 站点:
    • https://android.googlesource.com/platform/frameworks/base.git/+/master/core/java/android/webkit/

    • 镜像:
    • https://github.com/android/platform_frameworks_base/tree/master/core/java/android/webkit

  • 第三方开发者也在基于android_webview模块开发ChromeView
  • Third party developers work in progress to implement ChromeView based on android_webview module.
    • ChromeView有着和Android Webview一样的API.
    • https://github.com/pwnall/chromeview-src

浏览器中实现阅读模式

这里对阅读模式的定义是:去除网页上与主题内容无关的图片、导航、广告等等,给用户提供一个清爽的网页。在PC浏览器中,chrome/firefox都有这样的扩展/插件。我个人用的最多的是chrome上的印象笔记.悦读插件,和evernote整合,非常好用。从IOS 6开始,safari浏览器也提供了阅读器功能,用户界面如下:

safari_readmode_1 safari_readmode_2

当网页中主题内容比较明确、且文字内容较多时,地址栏上就会出现“阅读器”按钮,点击“阅读器”按钮,就会提供给用户一个清爽的网页。更绝的是,如果网页内容包含多个分页,“阅读器”模式下还可以自动整合,无需费力的点击下一页了,相当贴心,如下图所示:

safari_readmode_3

如果要在浏览器中实现这一个功能,可以有三种方法:

1、服务器端对网页进行处理

其思路和百度转码相同,就是在服务器端对网页进行处理,UC浏览器能够做到省流量,也是采用了这一技术。不过百度转码主要目的是为网页瘦身,所以处理出来的效果惨不忍睹。国外有一家公司,提供了免费的readability API,其口号是:

Transforms any article … into a calm, humane, readable experience

详情请访问http://www.readability.com。

使用国外免费的API,实现简单,无需架设服务器,但缺点也是明显的,速度不够理想,容易被墙,说不定哪天就不能使用了。

2、修改webkit,对DOM树进行处理

webkit中,有一个步骤就是解析html,形成DOM树,有了这个DOM树就好办了,有什么节点、节点属性、节点样式都一目了然。所以接下来要做的事情就是筛选主题内容,过滤无关紧要的节点。至于采用什么算法进行筛选,还没有找到现成的C++库,网上有一个C#库:NReadability 可供参考,如果对javascript比较熟的话,直接参考readability提供的js脚本也可以。

通过修改webkit实现阅读模式,速度快,更容易和浏览器界面进行整合(比如,safari中,只有文字较多的网页才会出现阅读器),也比较适合对js前端开发不熟悉的C++程序员,缺点是webkit比较复杂,需要对webkit了解深入,而且之后的维护也是个麻烦事情。

3、注入js,对DOM树进行处理

javascript具有操作DOM的能力,也可以应用样式表来修改节点的样式,所以通过注入JS脚本来实现阅读模式是一个不错的选择。chrome/firefox中扩展插件,或者一种称为bookmarklet的小片代码就是这样实现的。

回到chromium for android,ContentView提供了evaluateJavaScript方法为当前ContentView注入javascript,所以实现起来非常容易。

TODO

在safari中,实现了多页拼接的处理。Readability在一篇文章中也声明实现了多页合并的处理,不过我对javascript研究的不够多,还没有弄清是如何实现的。如果有精通web前端开发的同学一起探讨,非常欢迎。

chrome for android历史发布版本大集合

chrome for android的发布也进入了快通道,基本上windows/linux/android几个平台会同时发布新版本。不过google play上的app没法找到历史版本,有时为了测试对比,到处找一个历史版本。为此,本文整理了所有chrome for android的正式release版本的发布说明,历史版本可以从这里下载。

v28.0.1500.94

FRIDAY, JULY 19, 2013

Chrome for Android has been updated to 28.0.1500.94. This version contains minor bug fixes. A partial list of changes in this build is available in the SVN log. Interested in switching release channels?Find out how. If you find a new issue, please let us know by filing a bug.


v28.0.1500.64

WEDNESDAY, JULY 10, 2013

The Chrome team is excited to announce the promotion of Chrome 28 to the Stable channel. Chrome for Android 28.0.1500.64 contains a number of new features including:

  • Google Translate - When reading web pages in other languages, Chrome will automatically detect and offer to translate them to your language
  • Fullscreen on tablets - Similar to phones, simply scroll down the page and the toolbar will disappear.
  • New user interface for right-to-left (RTL) languages - An optimized interface for RTL languages including Arabic, Farsi, and Hebrew
  • Plenty of stability and performance fixes

A partial list of changes in this build is available in the SVN revision log. If you find a new issue, please let us know by filing a bug. More information about Chrome for Android is available on the Chrome site.

v27.0.1453.90

The Chrome team is excited to announce the promotion of Chrome 27 to the Stable channel. Chrome for Android 27.0.1453.90 contains a number of improvments including:

  • Fullscreen on phones - Scroll down the page and the toolbar will disappear.
  • Simpler searching - Searching from the omnibox will keep your search query visible in the omnibox, making it easier to edit, and show more on your search result page.
  • Client-side certificate support - You can now access sites that require you to use a certificate and Chrome will allow you to select an installed certificate
  • Tab history on tablets - Long press the browser back button to view your tab history
  • And a ton of stability and performance fixes

A partial list of changes in this build is available in the SVN revision log. If you find a new issue, please let us know by filing a bug. More information about Chrome for Android is available on the Chrome site.

v26.0.1410.58

WEDNESDAY, APRIL 3, 2013

The Chrome team is excited to announce the promotion of Chrome 26 to the Stable channel for Android. This update will be rolling out to Google Play over the next few hours.  Chrome for Android 26.0.1410.58 contains a number of updates including:

  • Password Sync
  • Autofill Sync
  • Fixed issue where blank page would be loaded rather than URL
  • Performance and stability improvements

You can find out more about the release on the Chrome blog.  If you find a new issue, please let us know by filing a bug.

v25.0.1364.169

FRIDAY, MARCH 8, 2013

Chrome for Android Stable Channel has been updated to 25.0.1364.169. This version is currently rolling out to Google Play over the next few hours.

This update improves font clarity and includes other stability fixes. Known issues are available on theChrome support site.

Interested in other release channels of Chrome for Android? A Beta channel is now available and can be run side by side with Stable. If you find a new issue, please let us know by filing a bug. More information on Chrome for Android is available on the Chrome site.

v25.0.1364.123

WEDNESDAY, FEBRUARY 27, 2013

The Chrome team is excited to announce the promotion of Chrome 25 to the Stable Channel for Android. Chrome 25.0.1364.123 is currently rolling out to Google Play over the next few hours. This update contains a huge number of changes over the previous release, including:

  • Improved scrolling performance
  • Increased responsiveness to pinch-zooming on pages
  • Faster interactive pages thanks to the latest version of the V8 javascript engine
  • Audio now continues to play while Chrome is in the background
  • Expanded support for HTML5 features
  • Support for pausing audio in Chrome when phone is in use (note: this requires an additional permission)

This update also picks up other important stability and performance fixes since the last release, along with some minor UI adjustments. Known issues are available on the Chrome support site.

Interested in other release channels of Chrome for Android? A Beta channel is now available and can be run side by side with Stable. If you find a new issue, please let us know by filing a bug. More information on Chrome for Android is available on the Chrome site.

拥抱chromium核心的Android WebView

概述

在移动平台上,Web APP和Native APP之争由来已久。在Apple AppStore取得巨大成功的今天,许多人开始看衰Web APP。但Web APP确实有着自己的优点,看看现在PC上页游的流行就可以知道,Web APP还是有存在的理由的。在Web APP和Native APP之争的同时,出现了第三种形态的APP,通常称之为混合应用程序(Hybrid App),即结合了HTML5和传统应用程序特征的一类应用程序。

开发混合应用程序(Hybrid App)的人员一定对Android SDK中的android.webkit.WebView这个类不陌生。它是一个View类,主要用途是用来渲染网页。得益于良好的封装,WebView屏蔽了底层webkit复杂的细节,应用程序只需要寥寥几行代码,就可以为应用程序增加HTML支持,为Hybrid App开发提供了强力支持。但Android WebView对HTML5的支持很差,性能也不行,直到Android 4.1,才有所改善。

如果能够将chromium嵌入到APP中作为Web Engine,Hybrid App开发无疑可以如虎添翼,所以国外的大拿整出来一个Chromium Embedded Framework,在此基础上,还引出了很多扩展项目,将这套框架搬到不同的语言。但目前还没有android的移植,而且这套Framework和android WebView API相差比较大,所以目前在Android APP中嵌入chromium还很困难。在开发Browser时,我们通过桥接/代理模式,也实现了一套UI挂两种内核,但两者的接口相差还是比较大,不是对Content API非常熟悉的,也不太容易使用。

chromium android_webview子项目

2013年4月,google放出重磅消息,退出WebKit项目,创建自己的渲染引擎Blink。作为Android Frameworks的WebKit for android,自然也会转向Blink(不知道为什么,webkit android移植代码一直没有upstream到webkit版本库)。但做为系统级的frameworks,要考虑到向后兼容,API是不能随便乱动的。其实在好几个月前,chromium代码库中就出现了android_webview这个目录,google早就有基于chromium打造新的WebView API的计划了。

在基于Chromium内核的Android WebView这篇文章中,分析了其实现结构:

enter image description here

可以看到,在ContentAPI之上,Chromium的WebView实现封装了一个新的模块AwContents,但这并非最终的WebView API,还需要一层桥接部分,将AwContents桥接到WebView,这就是图中的桥接模块,该模块位于Android源代码中,目前没有开源。这边没有开源,那边有人按奈不住了,整了一个开源ChromeView,实现这个桥接代码,有兴趣的可以看看。

参考资料:

1. WebKit和Blink

2. 基于Chromium内核的Android WebView

3. ChromeView project. https://github.com/pwnall/chromeview

chromium android webview即将来袭?

在android 4.0发布之前,就有传闻chrome即将成为android的内置浏览器。Android 4.0发布后,证实只是采用了chromium的部分代码,主体还是WebKit for Android。以google的实力,将chrome搬到android是轻而易举的,随后发布的chrome for android就证明了这一点。但google没有这么快替换系统内置浏览器,主要原因还在于API兼容。在WebView API没有完全替代方案之前,Android默认web引擎是不会替换掉的。几个月前开始,chromium代码库开始出现了android_webview,这个项目就是要在chromium的基础上封装出和原来的WebView API完全兼容的API。

随着chromium的快速更新,android_webview下面的代码越来越完善了。五一在家研究了一番,发现已经可以build出AndroidWebView.apk,经过简单的修改后,已经可以加载网页,渲染网页了,但缺少事件处理。您可以从这里下载测试APK。程序界面如下图所示:

chromium_android_webview

从代码中可以得出如下信息:

1、运行在单进程模式下

2、同时支持软件渲染和硬件加速渲染(目前AndroidWebView走的是软件渲染路径)

Android WebView做这样的选择是有道理的,毕竟android硬件环境参差不齐。多进程支持/GPU渲染可以留给各厂商自行优化。本次的Google I/O即将开幕了,Android 5.0是否会闪亮登场呢?chrome是否成为android内置浏览器呢?让我们拭目以待吧。

如果您对chromium android WebView有兴趣,敬请关注开源项目:https://github.com/mogoweb/chromium_webview