CEF框架:各种各样的Handle(一)
在前面几篇文章中,将CEF初始化的基本框架和流程介绍了一遍。那么当整个CEF框架启动后,程序员可以通过什么样的方式去获得CEF内部的信息,还有就是如何修改CEF的行为呢?在CEF框架中,都是通过各种各样的Handle来实现。
那么什么是Handle呢,我的理解就是和WIN32编程中的HANDLE差不多,就是一个句柄,是某个程序实体,或者内存中的实体对外暴露的一个接口,通过这个接口就可以得到这个实体或者对象的控制权,从而得到这个实体的各种信息,或者控制这个实体的行为。
甚至更简单的一点理解,也可以理解成一个指针。
在CEF框架中有非常多的Handle类,直接罗列容易让人晕菜,我做了一个简单线索图,供各位朋友参考(以CEF的CefSimple为例)。
CefApp类
整个CEF程序可以看成是一个App,所以CEF程序或者称作App,就是最顶层的需要管理操作的实体,而管理和控制这个实体的类就是CefApp类:
类的定义
类的定义在cef_app.h中:
///
// Implement this interface to provide handler implementations. Methods will be
// called by the process and/or thread indicated.
///
/*--cef(source=client,no_debugct_check)--*/
class CefApp : public virtual CefBaseRefCounted {
public:
///
// Provides an opportunity to view and/or modify command-line arguments before
// processing by CEF and Chromium. The |process_type| value will be empty for
// the browser process. Do not keep a reference to the CefCommandLine object
// passed to this method. The CefSettings.command_line_args_disabled value
// can be used to start with an empty command-line object. Any values
// specified in CefSettings that equate to command-line arguments will be set
// before this method is called. Be cautious when using this method to modify
// command-line arguments for non-browser processes as this may result in
// undefined behavior including crashes.
///
/*--cef(optional_param=process_type)--*/
virtual void OnBeforeCommandLineProcessing(
const CefString& process_type,
CefRefPtr<CefCommandLine> command_line) {}
///
// Provides an opportunity to register custom schemes. Do not keep a reference
// to the |registrar| object. This method is called on the main thread for
// each process and the registered schemes should be the same across all
// processes.
///
/*--cef()--*/
virtual void OnRegisterCustomSchemes(
CefRawPtr<CefSchemeRegistrar> registrar) {}
///
// Return the handler for resource bundle events. If
// CefSettings.pack_loading_disabled is true a handler must be returned. If no
// handler is returned resources will be loaded from pack files. This method
// is called by the browser and render processes on multiple threads.
///
/*--cef()--*/
virtual CefRefPtr<CefResourceBundleHandler> GetResourceBundleHandler() {
return nullptr;
}
///
// Return the handler for functionality specific to the browser process. This
// method is called on multiple threads in the browser process.
///
/*--cef()--*/
virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() {
return nullptr;
}
///
// Return the handler for functionality specific to the render process. This
// method is called on the render process main thread.
///
/*--cef()--*/
virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() {
return nullptr;
}
};
主要包含了下面几个函数:
- OnBeforeCommandLineProcessing,启动任何一个程序,都会输入一些命令行参数,这个函数提供创建app程序时,修改处理命令行参数的能力。
- GetBrowserProcessHandler,提供自定义浏览器进程实体控制器的能力。下面会提到。
- GetRenderProcessHandler,提供自定义renderer进程实体控制器的能力。下面也会提到。
- 其他的在simple例子里没怎么用,后续再说。
CefApp在simple例子中的使用
-
在程序的main函数,初始化的时候,就需要new一个CefApp的对象:
CefRefPtr<CefApp> app = new SimpleApp();
-
在cefsimple的例子里,SimpleApp同时担任了CefApp,GetBrowserProcessHandler和CefRenderProcessHandler的管理类,当然是可以分开的。
class SimpleApp : public CefApp, public CefBrowserProcessHandler, public CefRenderProcessHandler {...}
在SimpleApp中定义了GetBrowserProcessHandler函数,就是返回自身:
// CefApp methods: virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() OVERRIDE { return this; }
在SimpleApp中没有定义了GetRenderProcessHandler。
-
在初始化的过程函数CefExecuteProcess中传入了app这个对象。在CefExecuteProcess后续的一些类中,在不同的浏览器生命周期或者某种事件驱动中,就会调用到这几个函数:
context中的OnContextInitialized函数,调用了GetBrowserProcessHandler。void CefContext::OnContextInitialized() { CEF_REQUIRE_UIT(); if (application_) { // Notify the handler after the global browser context has initialized. CefRefPtr<CefRequestContext> request_context = CefRequestContext::GetGlobalContext(); auto impl = static_cast<CefRequestContextImpl*>(request_context.get()); impl->ExecuteWhenBrowserContextInitialized(base::BindOnce( [](CefRefPtr<CefApp> app) { CefRefPtr<CefBrowserProcessHandler> handler = app->GetBrowserProcessHandler(); if (handler) { handler->OnContextInitialized(); } }, application_)); } }
在浏览器代理里:
CefRefPtr<ChromeBrowserHostImpl> ChromeBrowserDelegate::CreateBrowserHost( content::WebContents* web_contents, const CefBrowserSettings& settings, CefRefPtr<CefClient> client, std::unique_ptr<CefBrowserPlatformDelegate> platform_delegate, scoped_refptr<CefBrowserInfo> browser_info, bool is_devtools_popup, CefRefPtr<ChromeBrowserHostImpl> opener, CefRefPtr<CefRequestContextImpl> request_context_impl) { CEF_REQUIRE_UIT(); DCHECK(web_contents); DCHECK(platform_delegate); DCHECK(browser_info); DCHECK(request_context_impl); // If |opener| is non-nullptr it must be a popup window. DCHECK(!opener.get() || browser_info->is_popup()); if (!client) { if (auto app = CefAppManager::Get()->GetApplication()) { if (auto bph = app->GetBrowserProcessHandler()) { client = bph->GetDefaultClient(); } } } ... }
这个就涉及太多的内部代码,就不一一说了,大家知道在程序启动后,由这两个函数来返回Browser和Renderer进程管理的handle类就行了。
CefBrowserProcessHandler类
上面提到了,在CefApp中返回了CefBrowserProcessHandler类的对象。
在cefsimple中,CefSimple类也充当了CefBrowserProcessHandler类的角色(继承)。在CefBrowserProcessHandler类中(cef_browser_process_handle.h),定义了下面这些函数:
///
// Class used to implement browser process callbacks. The methods of this class
// will be called on the browser process main thread unless otherwise indicated.
///
/*--cef(source=client,no_debugct_check)--*/
class : public virtual CefBaseRefCounted {
public:
///
// Called on the browser process UI thread to retrieve the list of schemes
// that should support cookies. If |include_defaults| is true the default
// schemes ("http", "https", "ws" and "wss") will also be supported. Providing
// an empty |schemes| value and setting |include_defaults| to false will
// disable all loading and saving of cookies.
//
// This state will apply to the CefCookieManager associated with the global
// CefRequestContext. It will also be used as the initial state for any new
// CefRequestContexts created by the client. After creating a new
// CefRequestContext the CefCookieManager::SetSupportedSchemes method may be
// called on the associated CefCookieManager to futher override these values.
///
/*--cef()--*/
virtual void GetCookieableSchemes(std::vector<CefString>& schemes,
bool& include_defaults) {}
///
// Called on the browser process UI thread immediately after the CEF context
// has been initialized.
///
/*--cef()--*/
virtual void OnContextInitialized() {}
///
// Called before a child process is launched. Will be called on the browser
// process UI thread when launching a render process and on the browser
// process IO thread when launching a GPU or plugin process. Provides an
// opportunity to modify the child process command line. Do not keep a
// reference to |command_line| outside of this method.
///
/*--cef()--*/
virtual void OnBeforeChildProcessLaunch(
CefRefPtr<CefCommandLine> command_line) {}
///
// Return the handler for printing on Linux. If a print handler is not
// provided then printing will not be supported on the Linux platform.
///
/*--cef()--*/
virtual CefRefPtr<CefPrintHandler> GetPrintHandler() { return nullptr; }
///
// Called from any thread when work has been scheduled for the browser process
// main (UI) thread. This callback is used in combination with CefSettings.
// external_message_pump and CefDoMessageLoopWork() in cases where the CEF
// message loop must be integrated into an existing application message loop
// (see additional comments and warnings on CefDoMessageLoopWork). This
// callback should schedule a CefDoMessageLoopWork() call to happen on the
// main (UI) thread. |delay_ms| is the requested delay in milliseconds. If
// |delay_ms| is <= 0 then the call should happen reasonably soon. If
// |delay_ms| is > 0 then the call should be scheduled to happen after the
// specified delay and any currently pending scheduled call should be
// cancelled.
///
/*--cef()--*/
virtual void OnScheduleMessagePumpWork(int64 delay_ms) {}
///
// Return the default client for use with a newly created browser window. If
// null is returned the browser will be unmanaged (no callbacks will be
// executed for that browser) and application shutdown will be blocked until
// the browser window is closed manually. This method is currently only used
// with the chrome runtime.
///
/*--cef()--*/
virtual CefRefPtr<CefClient> GetDefaultClient() { return nullptr; }
};
- OnContextInitialized函数,整个浏览器进程的上下文初始化时,可以完成一些定制动作。
- OnBeforeChildProcessLaunch,和CefApp类似,在process层面上也可以定制。
- GetPrintHandler,浏览器进程管理了整个浏览器的本地服务,打印等,这个就是返回打印的管理与处理类,可自定义。
- OnScheduleMessagePumpWork,在消息传递里面提到过的自己管理消息传递,配合pumpwork一起使用,后续有机会再细说,一般不使用。
- GetDefaultClient,默认的Client类管理器,在后面会讲到。
CefRenderProcessHandler类
和CefBrowserProcessHandler类类似,返回了一个Renderer的管理器:
在cef_render_process_handle.h文件中定义为:
class CefRenderProcessHandler : public virtual CefBaseRefCounted {
public:
typedef cef_navigation_type_t NavigationType;
///
// Called after WebKit has been initialized.
///
/*--cef()--*/
virtual void OnWebKitInitialized() {}
///
// Called after a browser has been created. When browsing cross-origin a new
// browser will be created before the old browser with the same identifier is
// destroyed. |extra_info| is a read-only value originating from
// CefBrowserHost::CreateBrowser(), CefBrowserHost::CreateBrowserSync(),
// CefLifeSpanHandler::OnBeforePopup() or CefBrowserView::CreateBrowserView().
///
/*--cef()--*/
virtual void OnBrowserCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefDictionaryValue> extra_info) {}
///
// Called before a browser is destroyed.
///
/*--cef()--*/
virtual void OnBrowserDestroyed(CefRefPtr<CefBrowser> browser) {}
///
// Return the handler for browser load status events.
///
/*--cef()--*/
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() { return nullptr; }
///
// Called immediately after the V8 context for a frame has been created. To
// retrieve the JavaScript 'window' object use the CefV8Context::GetGlobal()
// method. V8 handles can only be accessed from the thread on which they are
// created. A task runner for posting tasks on the associated thread can be
// retrieved via the CefV8Context::GetTaskRunner() method.
///
/*--cef()--*/
virtual void OnContextCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) {}
///
// Called immediately before the V8 context for a frame is released. No
// references to the context should be kept after this method is called.
///
/*--cef()--*/
virtual void OnContextReleased(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) {}
///
// Called for global uncaught exceptions in a frame. Execution of this
// callback is disabled by default. To enable set
// CefSettings.uncaught_exception_stack_size > 0.
///
/*--cef()--*/
virtual void OnUncaughtException(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context,
CefRefPtr<CefV8Exception> exception,
CefRefPtr<CefV8StackTrace> stackTrace) {}
///
// Called when a new node in the the browser gets focus. The |node| value may
// be empty if no specific node has gained focus. The node object passed to
// this method represents a snapshot of the DOM at the time this method is
// executed. DOM objects are only valid for the scope of this method. Do not
// keep references to or attempt to access any DOM objects outside the scope
// of this method.
///
/*--cef(optional_param=frame,optional_param=node)--*/
virtual void OnFocusedNodeChanged(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefDOMNode> node) {}
///
// Called when a new message is received from a different process. Return true
// if the message was handled or false otherwise. Do not keep a reference to
// or attempt to access the message outside of this callback.
///
/*--cef()--*/
virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message) {
return false;
}
};
- OnWebKitInitialized,渲染器进程WebKit初始化时调用。
- OnBrowserCreated,浏览器进程启动之后,render需要配合做的一些事情可以在这里自定义。
- OnBrowserDestroyed,浏览器进程关闭之前,render需要配合做的一些事情。
- OnContextCreated,render进程上下文创建时使用
- OnProcessMessageReceived,浏览器进程给render进程发送RPC信息时,render收到消息后就会调用,在CEF消息传递实战中就需要用到这个自定义函数。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!