logo资料库

Cef3详细介绍.pdf

第1页 / 共36页
第2页 / 共36页
第3页 / 共36页
第4页 / 共36页
第5页 / 共36页
第6页 / 共36页
第7页 / 共36页
第8页 / 共36页
资料共36页,剩余部分请下载后查看
这是一个翻译文档,持续更新中 这是一个翻译文档,持续更新中 CEF General Usage(CEF3预览) 介绍 CEF全称Chromium Embedded Framework,是一个基于Google Chromium 的开源项 目。Google Chromium项目主要是为Google Chrome应用开发的,而CEF的目标则是为第 三方应用提供可嵌入浏览器支持。CEF隔离底层Chromium和Blink的复杂代码,并提供一套产 品级稳定的API,发布跟踪具体Chromium版本的分支,以及二进制包。CEF的大部分特性都提 供了丰富的默认实现,让使用者做尽量少的定制即可满足需求。在本文发布的时候,世界上已经 有很多公司和机构采用CEF,CEF的安装量超过了100万。[CEF wikipedia]页面上有使用CEF 的公司和机构的不完全的列表。CEF的典型应用场景包括: 嵌入一个兼容HTML5的浏览器控件到一个已经存在的本地应用。 创建一个轻量化的壳浏览器,用以托管主要用Web技术开发的应用。 有些应用有独立的绘制框架,使用CEF对Web内容做离线渲染。 使用CEF做自动化Web测试。 CEF3是基于Chomuim Content API多进程构架的下一代CEF,拥有下列优势: 改进的性能和稳定性(JavaScript和插件在一个独立的进程内执行)。 支持Retina显示器。 支持WebGL和3D CSS的GPU加速。 类似WebRTC和语音输入这样的前卫特性。 通过DevTools远程调试协议以及ChromeDriver2提供更好的自动化UI测试。 更快获得当前以及未来的Web特性和标准的能力。 本文档介绍CEF3开发中涉及到的一般概念。 开始 使用二进制包 从源码编译(Building from Source Code) 示例应用程序(Sample Application) 重要概念(Important Concepts) C++ 封装(C++ Wrapper) 进程(Processes) 线程(Threads)
引用计数(Reference Counting) 字符串(Strings) 命令行参数(Command Line Arguments) 应用程序布局(Application Layout) 应用程序结构(Application Structure) Windows操作系统(Windows) Linux操作系统(Linux) Mac X平台(Mac OS X) 单一执行体(Single Executable) 分离子进程执行体(Separate Sub-Process Executable) 集成消息循环(Message Loop Integration) CefSettings CefBrowser和CefFrame CefApp CefClient Browser生命周期(Browser Life Span) 离屏渲染(Off-Screen Rendering) 投递任务(Posting Tasks) 进程间通信(Inter-Process Communication (IPC)) 处理启动消息(Process Startup Messages) 处理运行时消息(Process Runtime Messages) 异步JavaScript绑定(Asynchronous JavaScript Bindings) 通用消息转发(Generic Message Router) 自定义实现(Custom Implementation) 同步请求(Synchronous Requests) 网络层(Network Layer) 自定义请求(Custom Requests) 浏览器无关请求(Browser-Independent Requests) 请求响应(Request Handling) Scheme响应(Scheme Handler) 请求拦截(Request Interception) 其他回调(Other Callbacks) Proxy Resolution 使用二进制包 CEF3的二进制包可以在这个页面下载。其中包含了在特定平台(Windows,Mac OS X 以及 Linux)编译特定版本CEF3所需的全部文件。不同平台拥有共同的结构: cefclient Debug include libcef_dll Release Resources
tools 每个二进制包包含一个README.txt文件和一个LICENSE.txt文件,README.txt用以描述平台 相关的细节,而LICENSE.txt包含CEF的BSD版权说明。如果你发布了基于CEF的应用,则应该 在应用程序的某个地方包含该版权声明。例如,你可以在”关于”和“授权”页面列出该版权声明, 或者单独一个文档包含该版权声明。“关于”和“授权”信息也可以分别在CEF浏览器 的”about:license”和”about:credits”页面查看。 基于CEF二进制包的应用程序可以使用每个平台上的经典编译工具。包括Windows平台上的 Visual Studio,Mac OSX平台上的Xcode,以及Linux平台上的gcc/make编译工具链。CEF 项目的下载页面包含了这些平台上编译特定版本CEF所需的编译工具的版本信息。在Linux上编 译CEF时需要特别注意依赖工具链。 Tutorial Wiki页面有更多关于如何使用CEF3二进制包创建简单应用程序的细节。 从源码编译(Building from Source Code) CEF可以从源码编译,用户可以使用本地编译系统或者像TeamCity这样的自动化编译系统编 译。首先你需要使用svn或者git下载Chromium和CEF的源码。由于Chromium源码很大,只 建议在内存大于4GB的现代机器上编译。编译Chromium和CEF的细节请参 考BranchesAndBuilding页面。 示例应用程序(Sample Application) cefclient是一个完整的CEF客户端应用程序示例,并且它的源码包含在CEF每个二进制发布包 中。使用CEF创建一个新的应用程序,最简单的方法是先从cefclient应用程序开始,删除你不 需要的部分。本文档中许多示例都是来源于cefclient应用程序。 重要概念(Important Concepts) 在开发基于CEF3的应用程序前,有一些重要的基础概念应该被理解。 C++ 封装(C++ Wrapper) libcef 动态链接库导出 C API 使得使用者不用关心CEF运行库和基础代码。 libcef_dll_wrapper 工程把 C API 封装成 C++ API同时包含在客户端应用程序工程中,与 cefclient一样,源代码作为CEF二进制发布包的一部分共同发布。C/C++ API的转换层代码是 由转换工具自动生成。UsingTheCAPI 页面描述了如何使用C API。 进程(Processes) CEF3是多进程架构的。Browser被定义为主进程,负责窗口管理,界面绘制和网络交互。 Blink的渲染和Js的执行被放在一个独立的Render 进程中;除此之外,Render进程还负责Js Binding和对Dom节点的访问。 默认的进程模型中,会为每个标签页创建一个新的Render进程。其他进程按需创建,例如管理 插件的进程以及处理合成加速的进程等都是按需创建。 默认情况下,主应用程序会被多次启动运行各自独立的进程。这是通过传递不同的命令行参数给
CefExecuteProcess函数做到的。如果主应用程序很大,加载时间比较长,或者不能在非浏览 器进程里使用,则宿主程序可使用独立的可执行文件去运行这些进程。这可以通过配置 CefSettings.browser_subprocess_path变量做到。更多细节请参考Application Structure一节。 CEF3的进程之间可以通过IPC进行通信。Browser和Render进程可以通过发送异步消息进行双 向通信。甚至在Render进程可以注册在Browser进程响应的异步JavaScript API。 更多细节,请参考Inter-Process Communication一节。 通过设置命令行的 --single-process ,CEF3就可以支持用于调试目的的单进程运行模型。支持 的平台为:Windows,Mac OS X 和Linux。 线程(Threads) 在CEF3中,每个进程都会运行多个线程。完整的线程类型表请参照cef_thread_id_t。例如, 在Browser进程中包含如下主要的线程: TID_UI 线程是浏览器的主线程。如果应用程序在调用调用CefInitialize()时,传递 CefSettings.multi_threaded_message_loop=false,这个线程也是应用程序的主线 程。 TID_IO 线程主要负责处理IPC消息以及网络通信。 TID_FILE 线程负责与文件系统交互。 由于CEF采用多线程架构,有必要使用锁和闭包来保证数据的线程安全语义。 IMPLEMENT_LOCKING定义提供了Lock()和Unlock()方法以及AutoLock对象来保证不同代码 块同步访问数据。CefPostTask函数组支持简易的线程间异步消息传递。更多信息,请参 考Posting Tasks章节。 可以通过CefCurrentlyOn()方法判断当前所在的线程环境,cefclient工程使用下面的定义来确 保方法在期望的线程中被执行。 #define REQUIRE_UI_THREAD() ASSERT(CefCurrentlyOn(TID_UI)); #define REQUIRE_IO_THREAD() ASSERT(CefCurrentlyOn(TID_IO)); #define REQUIRE_FILE_THREAD() ASSERT(CefCurrentlyOn(TID_FILE)); 引用计数(Reference Counting) 所有的框架类从CefBase继承,实例指针由CefRefPtr管理,CefRefPtr通过调用AddRef()和 Release()方法自动管理引用计数。框架类的实现方式如下: class MyClass : public CefBase { public: // Various class methods here... private: // Various class members here... IMPLEMENT_REFCOUNTING(MyClass); // Provides atomic refcounting implementati on.
}; // References a MyClass instance CefRefPtr my_class = new MyClass(); 字符串(Strings) CEF为字符串定义了自己的数据结构。主要是出于以下原因: - libcef包和宿主程序可能使用不同的运行时,对堆管理的方式也不同。所有的对象,包括字符 串,需要确保和申请堆内存使用相同的运行时环境。 - libcef包可以编译为支持不同的字符串类型(UTF8,UTF16以及WIDE)。默认采用的是 UTF16,默认字符集可以通过更改cef_string.h文件中的定义,然后重新编译来修改。当使用宽 字节集的时候,切记字符的长度由当前使用的平台决定。 UTF16字符串结构体示例如下: typedef struct _cef_string_utf16_t { char16* str; // Pointer to the string size_t length; // String length void (*dtor)(char16* str); // Destructor for freeing the string on the corr ect heap } cef_string_utf16_t; 通过typedef来设置常用的字符编码。 typedef char16 cef_char_t; typedef cef_string_utf16_t cef_string_t; CEF提供了一批C语言的方法来操作字符串(通过#define的方式来适应不同的字符编码) cef_string_set 对制定的字符串变量赋值(支持深拷贝或浅拷贝)。 cef_string_clear 清空字符串。 cef_string_cmp 比较两个字符串。 CEF也提供了字符串不同编码之间相互转换的方法。具体函数列表请查阅cef_string.h和 cef_string_types.h文件。 在C++中,通常使用CefString类来管理CEF的字符串。CefString支持与std::string(UTF8)、 std::wstring(wide)类型的相互转换。也可以用来包裹一个cef_string_t结构来对其进行赋值。 和std::string的相互转换: std::string str = “Some UTF8 string”; // Equivalent ways of assigning |str| to |cef_str|. Conversion from UTF8 will occur if necessary. CefString cef_str(str); cef_str = str; cef_str.FromString(str);
// Equivalent ways of assigning |cef_str| to |str|. Conversion to UTF8 will oc cur if necessary. str = cef_str; str = cef_str.ToString(); 和std::wstring的相互转换: std::wstring str = “Some wide string”; // Equivalent ways of assigning |str| to |cef_str|. Conversion from wide will occur if necessary. CefString cef_str(str); cef_str = str; cef_str.FromWString(str); // Equivalent ways of assigning |cef_str| to |str|. Conversion to wide will oc cur if necessary. str = cef_str; str = cef_str.ToWString(); 如果是ASCII编码,使用FromASCII进行赋值: const char* cstr = “Some ASCII string”; CefString cef_str; cef_str.FromASCII(cstr); 一些结构体(比如CefSettings)含有cef_string_t类型的成员,CefString支持直接赋值给这些成 员。 CefSettings settings; const char* path = “/path/to/log.txt”; // Equivalent assignments. CefString(&settings.log_file).FromASCII(path); cef_string_from_ascii(path, strlen(path), &settings.log_file); 命令行参数(Command Line Arguments) 在CEF3和Chromium中许多特性可以使用命令行参数进行配置。这些参数采 用 --some-argument[=optional-param] 形式,并通过CefExecuteProcess()和CefMainArgs 结构(参考下面的应用资源布局章节)传递给CEF。在传递CefSettings结构给CefInitialize() 之前,我们可以设置CefSettings.command_line_args_disabled为true来禁用对命令行参数 的处理。如果想指定命令行参数传入主应用程序,实现 CefApp::OnBeforeCommandLineProcessing()方法。更多关于如何查找已支持的命令行选 项的信息,请查看client_switches.cpp文件的注释。 应用程序布局(Application Layout)
应用资源布局依赖于平台,有很大的不同。比如,在Mac OS X上,你的资源布局必须遵循特定 的app bundles结构;Window与Linux则更灵活,允许你定制CEF库文件与资源文件所在的位 置。为了获取到特定可以正常工作的示例,你可以从工程的下载页面下载到一个client压缩包。 每个平台对应的README.txt文件详细说明了哪些文件是可选的,哪些文件是必须的。 Windows操作系统(Windows) 在Windows平台上,默认的资源布局将libcef库文件、相关资源与可执行文件放置在同级目 录,文件夹结构大致如下: Application/ cefclient.exe <= cefclient application executable libcef.dll <= main CEF library icudt.dll <= ICU unicode support library ffmpegsumo.dll <= HTML5 audio/video support library libEGL.dll, libGLESv2.dll, … <= accelerated compositing support libraries cef.pak, devtools_resources.pak <= non-localized resources and strings locales/ en-US.pak, … <= locale-specific resources and strings 使用结构体CefSettings可以定制CEF库文件、资源文件的位置(查看README.txt文件或者本 文中CefSettings部分获取更详细的信息)。虽然在Windows平台上,cefclient项目将资源文 件以二进制形式编译进cefclient.rc文件,但是改为从文件系统加载资源也很容易。 Linux操作系统(Linux) 在Linux平台上,默认的资源布局将libcef库文件、相关资源与可执行文件放置在同级目录。注 意:在你编译的版本与发行版本应用程序中,libcef.so的位置是有差异的,此文件的位置取决 于编译可执行程序时,编译器rpath的值。比如,编译选项为“-Wl,-rpath,.”(“.”意思是当前文 件夹),这样libcef.so与可执行文件处于同级目录。libcef.so文件的路径可以通过环境变量中 的“ LD_LIBRARY_PATH ”指定。 Application/ cefclient <= cefclient application executable libcef.so <= main CEF library ffmpegsumo.so <-- HTML5 audio/video support library cef.pak, devtools_resources.pak <= non-localized resources and strings locales/ en-US.pak, … <= locale-specific resources and strings files/ binding.html, … <= cefclient application resources 使用结构体CefSettings可以定制CEF库文件、资源文件(查看README.txt文件或者本文中 CefSettings部分获取更详细的信息)。 Mac X平台(Mac OS X) 在Mac X平台上,app bundles委托给了Chromium实现,因此不是很灵活。文件夹结构大致
如下: cefclient.app/ Contents/ Frameworks/ Chromium Embedded Framework.framework/ Libraries/ ffmpegsumo.so <= HTML5 audio/video support library libcef.dylib <= main CEF library Resources/ cef.pak, devtools_resources.pak <= non-localized resources and strings *.png, *.tiff <= Blink image and cursor resources en.lproj/, … <= locale-specific resources and strings libplugin_carbon_interpose.dylib <= plugin support library cefclient Helper.app/ Contents/ Info.plist MacOS/ cefclient Helper <= helper executable Pkginfo cefclient Helper EH.app/ Contents/ Info.plist MacOS/ cefclient Helper EH <= helper executable Pkginfo cefclient Helper NP.app/ Contents/ Info.plist MacOS/ cefclient Helper NP <= helper executable Pkginfo Info.plist MacOS/ cefclient <= cefclient application executable Pkginfo Resources/ binding.html, … <= cefclient application resources 列表中的“Chromium Embedded Framework.framework”,这个未受版本管控的框架包含 了所有的CEF库文件、资源文件。使用install_name_tool与@executable_path,将 cefclient,cefclient helper等可执行文件,连接到了libcef.dylib上。 应用程序cefclient helper用来执行不同特点、独立的进程(Renderer,plugin等),这些进 程需要独立的资源布局与Info.plist等文件,它们没有显示停靠图标。用来启动插件进程的EH Helper清除了MH_NO_HEAP_EXECUTION标志位,这样就允许一个可执行堆。只能用来启动 NaCL插件进程的NP Helper,清除了MH_PIE标志位,这样就禁用了ASLR。这些都是tools文 件夹下面,用来构建进程脚本的一部分。为了理清脚本的依赖关系,更好的做法是检查发行版本 中的Xcode工程或者原始文件cefclient.gyp。
分享到:
收藏