CEF3研究(二)
应用程序结构
每个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种方式:
- 正常的调用CefDoMessageLoopWork() 函数来代替调用 CefRunMessageLoop()。每调用 CefDoMessageLoopWork()函数会对CEF消息循环执行单一集成。
应该谨慎使用这种方法。调用的方法也经常会挨饿CEF消息循环凑并且浏览器性能产生影响。调用方法过于频繁地将影响CPU使用率。 - 设置 CefSettings.multi_threaded_message_loop = true(仅Windows平台),这会引起CEF从主应用程序线程以单个线程运行浏览器的UI线程。这不会引起 CefDoMessageLoopWork()和 CefRunMessageLoop()的调用。. CefInitialize() 和CefShutdown() 应该在应用程序的主线程调用。 需要自己提供机制与应用程序主线程通信。
- 正常的调用CefDoMessageLoopWork() 函数来代替调用 CefRunMessageLoop()。每调用 CefDoMessageLoopWork()函数会对CEF消息循环执行单一集成。
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研究(二)的更多相关文章
- Fiddler实战深入研究(二)
Fiddler实战深入研究(二) 阅读目录 Fiddler不能捕获chrome的session的设置 理解数据包统计 请求重定向(AutoResponder) Composer选项卡 Filters选 ...
- (转载)Fiddler实战深入研究(二)
原文来源于:http://www.cnblogs.com/tugenhua0707/p/4637771.html,作者:涂根华 !个人觉得文章写的特别好,故收藏于此,感谢原作者的分享 Fiddler实 ...
- Fiddler实战深入研究(二)[转载]
Fiddler实战深入研究(二) 阅读目录 Fiddler不能捕获chrome的session的设置 理解数据包统计 请求重定向(AutoResponder) Composer选项卡 Filters选 ...
- Nginx源码研究二:NGINX的事件处理概论
NGINX作为服务端的应用程序,在客户端发出数据后,服务端在做着这样一些处理,数据先会经过网卡,网卡会和操作系统做交互,经过操作系统的协议栈处理,再和不同的应用程序交互. 在这里面涉及两个概念,一个是 ...
- tomcat 组件研究二--请求过程
上一篇博客大概总结了tomcat 的组件以及其组织方式,对于tomcat 的启动过程也进行进行了简单的总结,下面这篇博客,继续研究tomcat 处理请求的相关组件,其实就是主要研究Connectors ...
- [转] Java se 7新特性研究(二)
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp82 今天主要研究Java se 7中异常处理的新功能.从今天开始正在 ...
- CEF3研究(四)之javascript集成
一.介绍 谷歌浏览器和CEF使用V8JavaScript Engine作为内容的JavaScript实现.在浏览器中的每个窗口都有它自己在的JS上下文提供作用域和在窗口中安全的执行JS代码.CEF暴露 ...
- CEF3研究(三)
一.Off-Screen Rendering 脱屏绘制 CEF的脱屏渲染并不创建源生的浏览器窗口,而是CEF提供主应用程序在无效区域和像素buffer里渲染,然后主应用程序通过鼠标.键盘和焦点事件通知 ...
- android_activity_研究(二)
这次开始玩玩活动的生命周期.废话不说,先搞个小应用,大体思路是:主界面有两个按钮,一个按钮按下后,出现第二个界面:另一个按钮按下后,出现第三个界面,真他妈简单. 一.主界面: 1. 主界面布局xml文 ...
随机推荐
- NetBeans 默认编码修改方法
如果要NetBeans用UTF-8对文件进行解码,需要修改配置文件,具体方法如下: 1. 找到你的Netbeans安装目录下的etc文件夹,如D:\Program Files\NetBeans 8.2 ...
- django 数据库的一些操作
1.数据过滤: 使用filter()方法 >>> Publisher.objects.filter(name='Apress') [<Publisher: Apress> ...
- MATLAB读取每个文件夹下的badcsv文件后合并为总的badexcel文件
clear; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%读取子文件夹中bad.csv数据%并把所有数据写到一个excel文件中%%%%%%%%%%%%%%%%%% ...
- HTML页面中5种超酷的伪类选择器:hover效果
想在自己的网站中应用超酷的hover效果吗?也许你可以从如下的这些实例中获得一些灵感,如果你喜欢这些效果,也可以直接拷贝代码并应用到你的站点. 给平淡的站点带来活力 hover效果能给网页增加一些动态 ...
- Maven实战读书笔记(五):聚合与继承
Maven的聚合特性能够把项目的各个模块聚合在一起构建,而继承特性则能够帮助抽取各模块相同的依赖和插件等配置,在简化POM的同时,还能促进各个模块配置的一致性. 5.1 聚合 Maven聚合也称多模块 ...
- Function()构造函数与函数直接量
Function()构造函数与函数直接量 制作人:全心全意 在JavaScript中,除了可使用基本的function语句定义函数之外,还可以使用另外两种方式来定义,即使用Function()构造函数 ...
- spring-mvc junit测试
import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; impor ...
- Django之web本质
Django之web本质 Web的本质,是基于socket玩的. 在我们上网的过程中,一个访问请求是如何工作的. Web的框架: 网络的连接都是基于Socket 在连接中有TCP/UDP 和HTTP协 ...
- python str.format 中文对齐的细节问题
写了一个练手的爬虫...在输出的时候出现了让人很不愉♂悦的问题 像这样: 令人十分难受啊! #----------------------------------------------------- ...
- Spring Boot集成百度Ueditor
遇到的问题: 1.将ueditor加入/static目录下,能正常显示,但是出现“请求后台配置项http错误,上传功能将不能正常使用!”(解决在下面,都是自定义上传的,如果需要官方的示例,我也无能为力 ...