1. 应用程序结构

每个CEF3应用程序都有一个相同的结构:

  • 提供一个入口函数以初始化CEF和运行每个子进程逻辑和CEF消息处理
  • 提供一个CefApp子类处理某个进程的回调
  • 提供一个CefClinet子类处理某个浏览进程的回调
  • 调用CefBrowserHost::CreateBrowser()函数创建浏览进程实例并使用CefLifeSpanHandler来管理浏览生命周期

2. 入口函数

CEF3应用程序都是以多进程方式运行的。这些进程都可以使用相同的可执行文件和独立的可执行文件被分配在每个子进程上。每个可执行进程都有一个入口函数。
每个CEF3子进程运行时使用运行行来指定配置信息并通过CefMainArgs结构传递给CefExecuteProcess函数,CefMainArgs结构是跨平台的。
如:
 CefMainArgs main_args(argc, argv); 
 CefMainArgs main_args(hInstance);

3.单可执行体-单进程运行方式

当单可执行体时行时,入口函数CefExecuteProcess在不同进程类型之间需要区分。单可执行体结构只支持window和linux,不支持macos

4. 分离的子进程可执行体-多进程运行方式

当使用一个分离的子进程执行体时需要两个分离的进程和入口函数。

5. 消息循环集成

CEF可集成已经存在的应用程序消息循环来代替它自己的消息循环。有2种方式:

    1. 正常的调用CefDoMessageLoopWork() 函数来代替调用 CefRunMessageLoop()。每调用 CefDoMessageLoopWork()函数会对CEF消息循环执行单一集成。
      应该谨慎使用这种方法。调用的方法也经常会挨饿CEF消息循环凑并且浏览器性能产生影响。调用方法过于频繁地将影响CPU使用率。
    2. 设置 CefSettings.multi_threaded_message_loop = true(仅Windows平台),这会引起CEF从主应用程序线程以单个线程运行浏览器的UI线程。这不会引起 CefDoMessageLoopWork()和 CefRunMessageLoop()的调用。. CefInitialize() 和CefShutdown() 应该在应用程序的主线程调用。 需要自己提供机制与应用程序主线程通信。

6. CefSettings

CefSettings结构允许Cef配置应用程序类型。以下列出通用的成员:

  • single_process 设置为true将为浏览器和渲染使用单进程。也可配置使用单个进程的命令行开关。
  • browser_subprocess_path 子进程的单个执行体路径,
  • multi_threaded_message_loop为true表示浏览器进程的消息循环以单线程运行。
  • command_line_args_idsabled为true表示禁用使用标准的CEF和Chrominum命令行参数的浏览器进程配置的特性。
  • cache_path缓存数据保存在磁盘上,如果为空,内存缓存会被某些特性使用,临时磁盘缓存会被其他地方使用。如果不为空,如HTML5本地存储数据库会跨域。
  • locale locale字符串会传递给blink,默认为en-US
  • log_file为debuglog文件路径
  • log_severity日志等级
  • resources_dir_path资料的目录路径。即cef.pak或devtools_resources.pak文件的保存路径
  • locales_dir_path
  • locales_dir_path locales的保存路径
  • remote_debugging_port远程调试端口。范围在1024~65535

7.CefBrowser和CefFrame

CefBrowser和CefFrame对象用于向浏览器发送命令和接受回调函数的状态信息。每个CerBrowser对象有一个主CefFrame对象描述主窗口。有零个和多个描述子窗口。例如:一个浏览器加载两个窗口会有三个CefFrame对象,一个是顶层窗口,两个子窗口。

在主窗口中加载一个URL:
browser->GetMainFrame()->LoadURL(some_url);

调用浏览的返回按钮:
browser->GoBack();

获取主窗口的HTML内容

class Visitor : public CefStringVisitor {

public: Visitor() {}

virtual void Visit(const CefString& string) OVERRIDE { // Do something with |string|... }

IMPLEMENT_REFCOUNTING(Visitor);

};

browser->GetMainFrame()->GetSource(new Visitor());

CefBrowser和CefFrame对象分别存在浏览进程和渲染进程中。在浏览进程中可通过CefBrowser::GetHoset()函数控制主机行为,如获取窗口句柄:

CefWindowHandle window_handle = browser->GetHost()->GetWindowHandle();

8.CefApp

CefApp接口提供特殊进程回调的访问。重要的回调包括:
OnBeforeCommandLineProcessing 以编程的方式设置命令行
OnRegisterCustomSchemes 提供一个机会自定义主题
GetBrowserProcessHandler 指定浏览进程及包括 OnContextInitialized() 特定功能的处理者
GetRenderProcessHandler 渲染进程的处理者,包括JavaScript关联的回调和进程消息

9.CefClient

CefClient接口提供了浏览器实例的特定回调。一个CefClient实例可以被多个浏览器共享。重要的回调包括:
浏览器生命周期,上下文菜单,对话框,显示通知,拖拽事件,焦点事件,键盘事件的处理者
OnProcessMessageReceived 从渲染进程中发来的IPC消息的接受。

10.浏览器生命周期

Browser Life Space 以调用 CefBrowserHost::CreateBrowser()或CefBrowserHost::CreateBrowserSync()函数开始。 方便执行逻辑,包括CefBrowserProcessHandler::OnContextInitialized()或像WM_CREATE消息处理的调用。

CefLifeSpaceHandler类提供了管理浏览器生命周期的回调。

  • OnAfterCreated() 在浏览器对象被创建后立即调用,主应用程序通常用这个函数保存浏览器对象的引用,如:

    void MyClient::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
    // Must be executed on the UI thread.
    REQUIRE_UI_THREAD();
    // Protect data members from access on multiple threads.
    AutoLock lock_scope(this); // Deprecated -- see the “Threads” section. if (!m_Browser.get()) {
    // Keep a reference to the main browser.
    m_Browser = browser;
    m_BrowserId = browser->GetIdentifier();
    } // Keep track of how many browsers currently exist.
    m_BrowserCount++;
    }
  • CefBrowserHost::CloseBrowser() 销毁浏览进程 如:browser->GetHost()->CloseBrowser(false)
    如果浏览器是其他窗口的父窗口,那么这个关闭事件会引起父窗口的系统函数调用。那父窗口需要调用 CloseBrowser(false) 并等待第二个系统调用的关闭事件来指示浏览进程允许关闭。
    如果关闭通过Javascript事件或DoClose()回调函数处理,那第二个系统关闭事件就不会被发送。
    IsClosing()测试是否关闭,如果是第一次的系统关闭事件就返回false,每二次返回true; 
    第一个系统关闭事件是在窗口的WndProc函数中处理的
    case WM_CLOSE:

      if (g_handler.get() && !g_handler->IsClosing()) {
    CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
    if (browser.get()) {
    // Notify the browser window that we would like to close it. This will result in a call to
    // MyHandler::DoClose() if the JavaScript 'onbeforeunload' event handler allows it.
    browser->GetHost()->CloseBrowser(false); // Cancel the close.
    return 0;
    }
    } // Allow the close.
    break; case WM_DESTROY:
    // Quitting CEF is handled in MyHandler::OnBeforeClose().
    return 0;
    }
  • DoClose() 设置m_blsClosing标识并设置第二次系统关闭事件为false

    bool MyClient::DoClose(CefRefPtr<CefBrowser> browser) {
    // Must be executed on the UI thread.
    REQUIRE_UI_THREAD();
    // Protect data members from access on multiple threads.
    AutoLock lock_scope(this); // Closing the main window requires special handling. See the DoClose()
    // documentation in the CEF header for a detailed description of this
    // process.
    if (m_BrowserId == browser->GetIdentifier()) {
    // Notify the browser that the parent window is about to close.
    browser->GetHost()->ParentWindowWillClose(); // Set a flag to indicate that the window close should be allowed.
    m_bIsClosing = true;
    } // Allow the close. For windowed browsers this will result in the OS close
    // event being sent.
    return false;
    }
  • OnBeforeClose 在接受第二次OS关闭事件之前需要调用OnBeforeCloseb函数释放浏览器进程的引用。

CEF3研究(二)的更多相关文章

  1. Fiddler实战深入研究(二)

    Fiddler实战深入研究(二) 阅读目录 Fiddler不能捕获chrome的session的设置 理解数据包统计 请求重定向(AutoResponder) Composer选项卡 Filters选 ...

  2. (转载)Fiddler实战深入研究(二)

    原文来源于:http://www.cnblogs.com/tugenhua0707/p/4637771.html,作者:涂根华 !个人觉得文章写的特别好,故收藏于此,感谢原作者的分享 Fiddler实 ...

  3. Fiddler实战深入研究(二)[转载]

    Fiddler实战深入研究(二) 阅读目录 Fiddler不能捕获chrome的session的设置 理解数据包统计 请求重定向(AutoResponder) Composer选项卡 Filters选 ...

  4. Nginx源码研究二:NGINX的事件处理概论

    NGINX作为服务端的应用程序,在客户端发出数据后,服务端在做着这样一些处理,数据先会经过网卡,网卡会和操作系统做交互,经过操作系统的协议栈处理,再和不同的应用程序交互. 在这里面涉及两个概念,一个是 ...

  5. tomcat 组件研究二--请求过程

    上一篇博客大概总结了tomcat 的组件以及其组织方式,对于tomcat 的启动过程也进行进行了简单的总结,下面这篇博客,继续研究tomcat 处理请求的相关组件,其实就是主要研究Connectors ...

  6. [转] Java se 7新特性研究(二)

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp82   今天主要研究Java se 7中异常处理的新功能.从今天开始正在 ...

  7. CEF3研究(四)之javascript集成

    一.介绍 谷歌浏览器和CEF使用V8JavaScript Engine作为内容的JavaScript实现.在浏览器中的每个窗口都有它自己在的JS上下文提供作用域和在窗口中安全的执行JS代码.CEF暴露 ...

  8. CEF3研究(三)

    一.Off-Screen Rendering 脱屏绘制 CEF的脱屏渲染并不创建源生的浏览器窗口,而是CEF提供主应用程序在无效区域和像素buffer里渲染,然后主应用程序通过鼠标.键盘和焦点事件通知 ...

  9. android_activity_研究(二)

    这次开始玩玩活动的生命周期.废话不说,先搞个小应用,大体思路是:主界面有两个按钮,一个按钮按下后,出现第二个界面:另一个按钮按下后,出现第三个界面,真他妈简单. 一.主界面: 1. 主界面布局xml文 ...

随机推荐

  1. docker 新手入门 (web项目的部署)

    web项目的部署 1.首先我们下载centos镜像.docker pull centos 2.下载完成之后,我们首先要安装的是java环境  tomcat 和jdk 3.将下载好的软件放入到nmt目录 ...

  2. docker 镜像管理操作

    镜像特点 1. 分层存储的文件 2.一个软件运行环境 3.一个镜像可以创建多个容器 4.一种标准交付 5.不包含Linux内核而又精简的Linux操作系统 6.不是一个单一的文件而是由多层构成的,可以 ...

  3. Android studio Github 断开连接

    http://blog.csdn.net/agoodcoolman/article/details/50562301 使用软件:Android studio svn:Github 从github直接从 ...

  4. PHP14 动态图像处理

    学习要点 如何使用PHP中的GD库 设计验证码类 PHP图片处理 设计图像图处理类 如何使用PHP中的GD库 在网站上GD库通常用来生成缩略图,或者用来对图片加水印,或者用来生成汉字验证码,或者对网站 ...

  5. 雷林鹏分享:Lua 数据类型

    Lua是动态类型语言,变量不要类型定义,只需要为变量赋值. 值可以存储在变量中,作为参数传递或结果返回. Lua中有8个基本类型分别为:nil.boolean.number.string.userda ...

  6. IntelliJ IDEA集成工具Database连接MySQL8.0报错的解决方法

    直接用默认配置连接的话,会报以下错误: Connection to MySQL - @localhost failed. [08001] Could not create connection to ...

  7. Ubuntu 18的网络配置

    包括Ubuntu 18.04和18.10,设置为静态IP及DNS. sudo vim /etc/netplan/50-cloud-init.yaml network: ethernets: enp4s ...

  8. <a>标签的href 与 onclick 使用

    链接的onclick 事件被先执行,其次是href属性下的动作(页面跳转,或 javascript 伪链接): 假设链接中同时存在href 与onclick,如果想让href 属性下的动作不执行,on ...

  9. 性能优化 java 24 次阅读 · 读完需要 15 分钟 0

    摘要: 技术传播的价值,不仅仅体现在通过商业化产品和开源项目来缩短我们构建应用的路径,加速业务的上线速率,也会体现在优秀程序员在工作效率提升.产品性能优化和用户体验改善等小技巧方面的分享,以提高我们的 ...

  10. SV学习之interface

    普通的模块使用法:注意我们这里只实现了部分功能....不是完全的读写模块....     module mem_core(   input logic wen,  input logic ren,   ...