Android 4.4 WebView实现分析

泡在网上的日子 / 文 发表于2014-11-06 20:13 次阅读 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而开发。

转自:放飞梦想的博客  该博客中有大量关于webview 以及Chromium的东西。


收藏 赞 (1) 踩 (2)
上一篇:Android 4.4 中 WebView 使用注意事项
自Android 4.4起,Android中的WebView开始基于Chromium( 这大概是因为Android部门负责人从Andy Rubin变成了Chrome部门的主管Sundar Pichai了吧,^_^)。 这个改变使得WebView的性能大幅度提升,并且对HTML5, CSS3, and JavaScript有了更好的支持。 那么,作
下一篇:android handler的警告Handler Class Should be Static or Leaks Occur
在使用Handler更新UI的时候,我是这样写的: public class SampleActivity extends Activity { private final Handler mLeakyHandler = new Handler() { @Override public void handleMessage(Message msg) { // TODO } }} 看起来很正常的,但是 Android Lin