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. contos7 使用zabbix监控物理磁盘状态实例

    一.系统环境: 物理机:dell R640 操作系统:centos7 二.安装MegaCli 监控主要是通过MegaCli 软件获取到物理主机的read及硬盘相关状态信息.然后通过zabbix的自定义 ...

  2. DECLARE - 定义一个游标

    SYNOPSIS DECLARE name [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ] CURSOR [ { WITH | WITHOUT } HOLD ...

  3. tabsGif

    tabsGif

  4. 如何在一次请求中通过JS中获取Url中的参数

    从A跳转到B,携带参数 例如: /pc/B.jsp?item=123456 B页面在js可以直接用 var item='${param.item}'; 这样就拿到啦 还有一种方法 定义一个函数   f ...

  5. Calling method 'get' is not valid without an active transaction

    在进行使用注解来配置Spring和Hibernate的整合的时候, 遇到了这个问题, 它的意思是说在调用'get'方法的时候,没有活动的事务. 原因分析: Hibernate强制要求在进行数据库操作的 ...

  6. No-4.文件和目录常用命令

    文件和目录常用命令 结构 查看目录内容 ls 切换目录 cd 创建和删除操作 touch rm mkdir 拷贝和移动文件 cp mv 查看文件内容 cat more grep 其他 echo 重定向 ...

  7. 在window下搭建即时即用的hyperledger fabric 的环境

    有版本号的严格按要求,遇到不少坑 1)安装git  版本无要求 2)安装go  1.9   配置环境变量 3)安装Vagrant  1.9.4 4)安装VirtualBox  5.1.28 5)在go ...

  8. scrapy example

    scrapy example scrapy with pycharm import win32api 出现ImportError: DLL load failed 错误的解决方法 pip instal ...

  9. 如何用纯 CSS 创作 404 文字变形为 NON 文字的交互特效

    效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/ZoxjXm 可交互视频教 ...

  10. 使用js获取页面的各种高度

    使用js获取相关高度: 获取网页被滚动条卷去的高度——兼容写法: scrollHeight = documen.body.scrollTop || document.documentElement.s ...