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. 什么是Entitlement

    Entitlement(权限),可以想象成App里用于描述该App可以调用哪些服务的字符串.苹果的操作系统(mac os或者iOS)会通过检查这个串,决定这个应用是否可以调用相关功能.比如iCloud ...

  2. vue :class 可以接收 字符串 数组 和 对象 对象里面的key值 根据true或false 显示不显示

    vue :class 可以接收 字符串 数组 和 对象 对象里面的key值 根据true或false 显示不显示 https://cn.vuejs.org/v2/guide/class-and-sty ...

  3. 用Multisim实现彩灯循环控制器

    2019/06/06 !转载请注明出处 1.设计任务目的与要求 1.1 展示器件 10路彩灯分别用10个发光二极管L0.L1…..L9模拟,发光二极管L0.L1…..L9从左到右排列. 1.2 要求显 ...

  4. HDU-4791-Alice‘s Print Service

    分析: 1.由于价格是递减的,所以可能出现si*pi>sj*pj(j>i).所以要有一个数组来储存当前端点的最小值. 2.然后二分查找当前的si,比较q*p[i]和M[i+1].不过在这之 ...

  5. 每日命令:(14)tune2fs

    tune2fs简介 tune2fs是调整和查看ext2/ext3文件系统的文件系统参数,Windows下面如果出现意外断电死机情况,下次开机一般都会出现系统自检.Linux系统下面也有文件系统自检,而 ...

  6. linux破解root登录密码,并重置

    重启系统后按'e'键,进入编辑模式,在'UTF -8'后空格输入'rd.break'后,按快捷键'Ctrl+X'进入新界面进行编辑,代码如下: switch_root:/# mount -o remo ...

  7. 为什么JavaScript里面0.1+0.2 === 0.3是false

    以下这一篇说明的很详细:彻底理解0.1 + 0.2 === 0.30000000000000004的背后 0.1+0.2 === 0.3 //返回是false, 这是为什么呢?? 我们知道浮点数计算是 ...

  8. 快速简单高效的搭建 SolrCloud 集群

    转https://segmentfault.com/a/1190000008634902 集群配置 集群中的每台机器都要按照以下说明进行配置启动 首先到 solr 安装目录的 bin 下,编辑 sol ...

  9. LeetCode(80)Remove Duplicates from Sorted Array II

    题目 Follow up for "Remove Duplicates": What if duplicates are allowed at most twice? For ex ...

  10. tcpcopy简单用法

    这篇文章介绍下网易开源的流量重放(replay)工具TCPCopy,说是简单介绍,绝对不是谦虚,因为自己了解的确实也不多.为什么不甚了解呢,大家可以到TCPCopy的官方仓库看看,https://gi ...