理解WebKit和Chromium: 基于Chromium内核的Android WebView

本文详细介绍了Android WebView从基于WebKit内核转变为基于Chromium内核的改进过程,包括渲染机制和进程变化,展示了如何通过编译目标体验新功能,并讨论了性能提升和安全性考量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明原文地址:http://blog.youkuaiyun.com/milado_nju

## 概述

熟悉Android系统和HTML编程的人可能都听说过Android提供的一个重要类android.webkit.WebView,它继承于View类,这是它同其它很多控件的相似之处。不同之处在于,它能够用来渲染网页。当前,WebView的实现是基于现有的缺省WebKit内核(Android缺省浏览器是基于WebView构建),它不同于chromium所使用的WebKit内核,虽然它们都叫WebKit。

目前,它被广泛的用在众多的Android应用程序中,通常我们称之为混合应用程序(Hybridapplications,意思是结合了HTML5和传统的应用程序特征)。遗憾的是,它对HTML5的支持很差,而且也没有新的功能被加入进来,同时,Chromium的Android版正在积极向前发展,更多的针对该平台的HTML5能力和优化逐步被实现和采用,那么是否也可以使用Chrome的内核来实现该WebView呢?答案当然是肯定的。

目前,该项目已经启动,其核心思想保持WebView的API兼容性,也就是说只是将内部的实现从当前缺省WebKit内核变了Chromium的内核,但是原有的WebViewAPI保持不变,这样对于WebView的用户来说,不需要做任何改变,便可以使用上功能更多性能更好的渲染内核了。

你可以通过编译目标“android_webview_apk”来尝试一下它的功能,这也是基于WebView的一个简单实例应用程序,类比一下就如同content模块和ContentShell的关系。

## 结构

在今后的Android某个版本之后,毫无疑问,基于Chromium内核的WebView将会取代现有WebView的实现。初看一下,目前的代码结构如下图所示,在ContentAPI之上,Chromium的WebView实现封装了一个新的类AwContents,该类主要基于ContentViewCore类的实现,不同的是,AwContents需要基于一个原来存在于“chrome/”目录下的模块(图中的BrowserComponents),但是AwContents不应该依赖该目录,所以,将chrome中的一些所谓的浏览器模块化是Chromium的一个方向,目前,一些模块以及从chrome中抽取出来了,参见“components/”,具体介绍见参考资料2。

AwContents提供的不是WebView的API,所以,需要一层桥接部分,将AwContents桥接到WebView,这就是图中的桥接模块,该模块位于Android源代码中,目前没有开源,应该稍后会开放出来(注,现在这部分代码已经可以看到了,读者可以上Android的官网上浏览源代码https://android.googlesource.com/platform/frameworks/base.git/+/master/core/java/android/webkit/)。


今后,WebView有什么变化,将会在该篇文章中持续更新,欢迎大家关注。

##新变化

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

1.渲染机制

因为WebView提供的是一个View控件,那么View控件的容器可能接受储存在CPU中的结构(如bitmap),也可能是储存在GPU内存中的结构(如surface),所以它需要提供两种不同的输出结果。那么是否意味了WebView提供软件渲染和GPU硬件渲染两种方式呢?答案是否定的。

目前,Chromiumfor Android不提供网页软件渲染,只有GPU硬件渲染一种方式,其渲染的结果由合成器生成。那么,如何生成bitmap呢?目前答案是通过OpenGL ES的回读方式。当合成器每合成一帧时候,AwContents将该帧保存在一个PictureMap中,当UI需要重新绘制时候,便把当前的Picture取出,绘制在当前View的canvas中,如下图所示,所以它其实什么也不能做,不接受事件输入,不能滚动等等,只能看到一个渲染结果。同时,这样做会导致及其低效的性能。当然,这只是一个临时方案。


当前,对于Compositor的结果输出到给定View的GPU内存这种方式,AwContents还不支持,工作正在进行中。 为什么?因为Chromium即将引入一种新的合成器UberCompositor++,该合成器支持输出到GPU和CPU内存两种方式,今后将对其作介绍。

2.进程

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

## 源文件目录

android_webview/

该目录包含了支持webview所需的所有相关类

## 参考资料

1.http://developer.android.com/reference/android/webkit/WebView.html

2.http://www.chromium.org/developers/design-documents/browser-components

By yongsheng@chromium.org

<think>我们正在讨论Android WebView如何封装使用Chromium。根据引用内容,我们可以总结如下: 1. 在Android 4.4之后,WebView内核WebKit切换到了Chromium(即Chromium Android WebView,简称CAW)[^3]。 2. Android WebView的架构中,`android.webkit.WebView`是SDK中定义的公共API,而Chromium Android WebView属于Chromium项目的一部分[^1]。 3. WebView Glue层(Java实现)将WebView的API桥接到Chromium Android WebView的实现上[^1]。 4. Chromium Android WebView封装了Chromium的Content层,提供了`AwBrowserProcess``AwContents`类,分别对应Chromium的`BrowserStartupController``ContentViewCore`[^2]。 5. 在具体实现中,当我们在App的UI中嵌入一个WebView时,WebView内部会创建一个`WebViewChromium`对象,该对象基于Chromium的`android_webview`模块[^2]。 6. `android_webview`模块提供了对Content层的封装,同时兼具了一些Embedder(嵌入者)的行为,并且还集成了部分Browser Components(如自动填充、PDF导出等)[^1]。 封装机制的具体层次结构(参考引用[4]的代码层次图): - 顶层:`WebView.java`(SDK公共API) - 第二层:AndroidChromium的封装层(Java桥接层,即WebView Glue) - 第三层:Content模块(导航控制,核心层) - 第四层:blink public web API(供外部操控内核) - 第五层:WebCore(被抽离形成blink) - 第六层:blink public platform API(要求外部实现,如网络) - 第七层:Content模块(在I/O线程中操作) - 底层:网络库 因此,Android WebViewChromium的封装主要是通过一个Java桥接层(WebView Glue)将Android SDK的WebView API调用转发给Chromiumandroid_webview模块,该模块再通过封装Chromium Content层的核心功能(如导航、渲染、网络等)来实现WebView的功能。 总结:Android WebView通过多层封装,将Chromium的核心功能(主要是Content模块)暴露给Android应用开发者,同时保持了与Android SDK WebView API的兼容性。</think>### Android WebViewChromium 的封装机制 Android WebViewChromium 的封装是通过多层架构实现的,核心是将 Chromium 的 Content 模块适配到 Android 框架中,同时保持 WebView API 的兼容性。具体机制如下: #### 1. **架构分层** - **顶层(Java API层)** `android.webkit.WebView` 提供标准 SDK 接口,开发者直接调用这些 API 操作网页[^1]。 ```java WebView webView = findViewById(R.id.webview); webView.loadUrl("https://example.com"); ``` - **桥接层(WebView Glue)** 通过 Java 层将 WebView API 调用转换为 Chromium 操作。例如: - `WebView.loadUrl()` → 调用 `AwContents.loadUrl()`(Chromium 封装层) - 处理 Android 生命周期事件(如 `onPause()`)并同步到 Chromium 内核[^1][^2]。 - **Chromium 封装层(android_webview 模块)** 核心类包括: - `AwBrowserProcess`:封装 Chromium 的 `BrowserStartupController`,负责进程初始化[^2]。 - `AwContents`:封装 `ContentViewCore`,管理网页渲染、导航等核心功能[^2][^4]。 #### 2. **关键封装技术 - **功能映射** Chromium 的 Blink 渲染引擎通过 `blink public web API` 暴露接口,由 `AwContents` 实现具体功能(如加载页面、执行 JavaScript)[^4]。 ```cpp // 伪代码:AwContents 对 ContentViewCore 的封装 class AwContents { void LoadUrl(String url) { content_view_core_->LoadUrl(url); // 调用 Chromium Content 层 } } ``` - **线程模型适配** Android UI 主线程与 Chromium 的多进程架构(RenderProcess、GPUProcess)通过 IPC 通信。例如: - 网络请求在 I/O 线程处理(`Content Module (I/O thread)`)[^4]。 - 渲染结果通过共享内存传递到 UI 线程显示。 - **组件集成** 复用 Chromium 的浏览器组件: - **自动填充(AutoFill)**:通过 `Browser Components` 集成[^1]。 - **PDF 导出**:调用 Chromium 的 PDF 模块实现[^1]。 #### 3. **兼容性处理 - **内核切换** Android 4.4+ 使用 Chromium 替代 WebKit,通过 `WebViewChromium` 对象动态加载不同内核[^2][^3]。 - **ROM 适配** 针对第三方 ROM 修改 WebView 的行为,通过抽象层隔离差异(如重写 `WebViewProvider` 接口)[^3]。 #### 4. **性能优化 - **硬件加速**:通过 Chromium 的 GPU 渲染管线实现。 - **资源复用**:多个 WebView 共享同一个 Chromium 进程[^2]。 ### 封装流程示例 当调用 `WebView.loadUrl()` 时: 1. Java 层接收请求 → 通过 JNI 调用 `AwContents.loadUrl()`。 2. `AwContents` 转发请求至 Chromium 的 `Content Layer`。 3. `Content Layer` 启动网络请求(`Network Stack`)并加载页面[^4]。 4. 渲染结果通过 `blink public platform API` 返回给 `AwContents`。 5. `AwContents` 将渲染数据传递到 Android Surface 显示。 ### 总结 Android WebView 通过 **Java 桥接层 + Chromium 封装层** 的架构,将 Chromium 的 Content 模块功能映射为标准 WebView API。这种设计既保留了 Chromium 的高性能特性,又确保了与 Android 框架的兼容性[^1][^2][^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值