CEF(Chromium Embedded Framework) 是什么?
CEF 的官网介绍的很简洁:A simple framework for embedding chromium browser windows in other applications. 具体地说就是一个可以将浏览器功能(页面渲染,JS 执行)嵌入到其他应用程序的框架。
如果你对上面这句话不是特别理解,可以看看这篇文章对 CEF 的介绍。如果你对 CEF 的底层感兴趣,建议你去这里,这里,这里,还有这里看看。
CEF 的应用场景
CEF 作为嵌入式浏览器框架最适合的应用场景应该是 HTML 页面渲染,所以很多程序都基于 CEF 来为应用程序提供 HTML 页面渲染的功能,如有道笔记,Evernote,GitHub Window Client,Q+,Adobe Brackets 等。此外还有一些基于 Web 的桌面应用也使用了 CEF,更多的应用你可以 Google 一下。
CEF 的好处和优点
基于 Chrome,开源,稳定,跨平台,性能高,新特性多,支持很多 HTML5 特性,等等等。
CEF 的缺陷
太太太太大。。。。动辄几十M的动态库,一个小程序打包后也有20多M,受不了 ;-(
CEF3 作为一个基于 Chromium 的嵌入式浏览器框架为开发者提供了几个基本的接口类来完成一些基本功能。
CefApp 类介绍
CefApp: 与进程,命令行参数,代理,资源管理相关的回调类,用于让 CEF3 的调用者们定制自己的逻辑。与该类相关的几个函数如下:
int CefExecuteProcess(const CefMainArgs& args, CefRefPtr<CefApp> application);
bool CefInitialize(const CefMainArgs& args, const CefSettings& settings, CefRefPtr<CefApp> application);
CefExecuteProcess() 和 CefInitialize() 都可以将 CefApp 类的一个对象做为参数传递进来。 另外,CefApp 的主要接口如下,其中 OnBeforeCommandLineProcessing 函数在你的程序启动 CEF 和 Chromium 之前给你提供了修改命令行参数的机会; OnRegisterCustomSchemes 用于注册自定义 schemes,剩下的接口用于返回相关回调函数的 Handler。
// 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. 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. virtual void OnRegisterCustomSchemes( CefRefPtr<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. virtual CefRefPtr<CefResourceBundleHandler> GetResourceBundleHandler() { return NULL; } // Return the handler for functionality specific to the browser process. This // method is called on multiple threads in the browser process. virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() { return NULL; } // Return the handler for functionality specific to the render process. This // method is called on the render process main thread. virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() { return NULL; }
CefClient 类介绍
CefClient: 回调管理类,该类的对象作为参数可以被传递给CefCreateBrowser() 或者 CefCreateBrowserSync() 函数。该类的主要接口如下:
// Return the handler for context menus. If no handler is provided the default // implementation will be used. virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() { return NULL; } // Return the handler for dialogs. If no handler is provided the default // implementation will be used. virtual CefRefPtr<CefDialogHandler> GetDialogHandler() { return NULL; } // Return the handler for browser display state events. virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() { return NULL; } // Return the handler for download events. If no handler is returned downloads // will not be allowed. virtual CefRefPtr<CefDownloadHandler> GetDownloadHandler() { return NULL; } // Return the handler for focus events. virtual CefRefPtr<CefFocusHandler> GetFocusHandler() { return NULL; } // Return the handler for geolocation permissions requests. If no handler is // provided geolocation access will be denied by default. virtual CefRefPtr<CefGeolocationHandler> GetGeolocationHandler() { return NULL; } // Return the handler for JavaScript dialogs. If no handler is provided the // default implementation will be used. virtual CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() { return NULL; } // Return the handler for keyboard events. virtual CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() { return NULL; } // Return the handler for browser life span events. virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() { return NULL; } // Return the handler for browser load status events. virtual CefRefPtr<CefLoadHandler> GetLoadHandler() { return NULL; } // Return the handler for off-screen rendering events. virtual CefRefPtr<CefRenderHandler> GetRenderHandler() { return NULL; } // Return the handler for browser request events. virtual CefRefPtr<CefRequestHandler> GetRequestHandler() { return NULL; } // 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. virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message) { return false; }
CefClient 中返回的回调类包括:
CefContextMenuHandler,回调类,主要用于处理 Context Menu 事件。
CefDialogHandler,回调类,主要用来处理对话框事件。
CefDisplayHandler,回调类,处理与页面状态相关的事件,如页面加载情况的变化,地址栏变化,标题变化等事件。
CefDownloadHandler,回调类,主要用来处理文件下载。
CefFocusHandler,回调类,主要用来处理焦点事件。
CefGeolocationHandler,回调类,用于申请 geolocation 权限。
CefJSDialogHandler,回调类,主要用来处理 JS 对话框事件。
CefKeyboardHandler,回调类,主要用来处理键盘输入事件。
CefLifeSpanHandler,回调类,主要用来处理与浏览器生命周期相关的事件,与浏览器对象的创建、销毁以及弹出框的管理。
CefLoadHandler,回调类,主要用来处理浏览器页面加载状态的变化,如页面加载开始,完成,出错等。
CefRenderHandler,回调类,主要用来处在在窗口渲染功能被关闭的情况下的事件。
CefRequestHandler,回调类,主要用来处理与浏览器请求相关的的事件,如资源的的加载,重定向等。
CefBrowserHost 类介绍
CefBrowserHost: 该类在浏览器窗口来看代表了 browser 进程,同时也暴露了与浏览器窗口相关的接口,该类的方法只能在 browser 进程中调用,但可以在 browser 进程的任意线程中被调用。该类的主要方法如下:
- 创建浏览器对象。
需要传入的参数包括 CefWindowInfo 对象,CefClient 对象,默认的 URL, 以及浏览器启动时参数设置。
public static bool CreateBrowser(const CefWindowInfo& windowInfo, CefRefPtr<CefClient> client, const CefString& url, const CefBrowserSettings& settings);
public static CefRefPtr<CefBrowser> CreateBrowserSync( const CefWindowInfo& windowInfo, CefRefPtr< CefClient > client, const CefString& url, const CefBrowserSettings& settings);
- 请求关闭浏览器对象。该函数被调用是会触发 JS 'onbeforeunload' 事件,如果参数 force_close为 false,并且提供了 onbeforeunload 事件的回调函数,则提示用户是否关闭浏览器,此时用户可以选取取消操作。如果 force_close为 true,则直接关闭浏览器。
public virtual void CloseBrowser(bool force_close)= 0;
- 获取浏览器对象(在 CefBrowser 类中可以通过调用 GetHost() 获取与之对应的 CefBrowserHost)
public virtual CefRefPtr< CefBrowser > GetBrowser()= 0;
- 获取 CefClient 对象
public virtual CefRefPtr< CefClient > GetClient()= 0;
- 获取该浏览器对象的窗口句柄,如果是弹出窗口,则返回 NULL。
public virtual CefWindowHandle GetOpenerWindowHandle()= 0;
CefBrowser 类介绍
CefBrowser: 该类代表一个浏览器对象,在 browser 进程中该类的方法可以被任意线程调用。在 render 进程中只能在主线程被调用。该类的主要方法包括:
// Returns the browser host object. This method can only be called in the // browser process. virtual CefRefPtr<CefBrowserHost> GetHost() =0; // Returns true if the browser can navigate backwards. virtual bool CanGoBack() =0; // Navigate backwards. virtual void GoBack() =0; // Returns true if the browser can navigate forwards. virtual bool CanGoForward() =0; // Navigate forwards. virtual void GoForward() =0; // Returns true if the browser is currently loading. virtual bool IsLoading() =0; // Reload the current page. virtual void Reload() =0; // Reload the current page ignoring any cached data. virtual void ReloadIgnoreCache() =0; // Stop loading the page. virtual void StopLoad() =0; // Returns the globally unique identifier for this browser. virtual int GetIdentifier() =0; // Returns true if this object is pointing to the same handle as |that| // object. virtual bool IsSame(CefRefPtr<CefBrowser> that) =0; // Returns true if the window is a popup window. virtual bool IsPopup() =0; // Returns true if a document has been loaded in the browser. virtual bool HasDocument() =0; // Returns the main (top-level) frame for the browser window. virtual CefRefPtr<CefFrame> GetMainFrame() =0; // Returns the focused frame for the browser window. virtual CefRefPtr<CefFrame> GetFocusedFrame() =0; // Returns the frame with the specified identifier, or NULL if not found. virtual CefRefPtr<CefFrame> GetFrame(int64 identifier) =0; // Returns the frame with the specified name, or NULL if not found. virtual CefRefPtr<CefFrame> GetFrame(const CefString& name) =0; // Returns the number of frames that currently exist. virtual size_t GetFrameCount() =0; // Returns the identifiers of all existing frames. virtual void GetFrameIdentifiers(std::vector<int64>& identifiers) =0; // Returns the names of all existing frames. virtual void GetFrameNames(std::vector<CefString>& names) =0; // Send a message to the specified |target_process|. Returns true if the // message was sent successfully. virtual bool SendProcessMessage(CefProcessId target_process, CefRefPtr<CefProcessMessage> message) =0;
CefFrame 类介绍
CefFrame: 表示浏览器窗口中的一个 frame,在 browser 进程中该类的方法可以被任意线程调用(简单理解就是 Frame 标识一个页面,通过该类开发者可以加载某一URL 或者一段 HTML 代码,获取页面的源码和文本,URL,V8 执行上下文,访问页面中的 DOM)。该类的主要方法如下:
// True if this object is currently attached to a valid frame. virtual bool IsValid() =0; // Execute undo in this frame. virtual void Undo() =0; // Execute redo in this frame. virtual void Redo() =0; // Execute cut in this frame. virtual void Cut() =0; // Execute copy in this frame. virtual void Copy() =0; // Execute paste in this frame. virtual void Paste() =0; // Execute delete in this frame. virtual void Delete() =0; // Execute select all in this frame. virtual void SelectAll() =0; // Save this frame's HTML source to a temporary file and open it in the // default text viewing application. This method can only be called from the // browser process. virtual void ViewSource() =0; // Retrieve this frame's HTML source as a string sent to the specified // visitor. virtual void GetSource(CefRefPtr<CefStringVisitor> visitor) =0; // Retrieve this frame's display text as a string sent to the specified // visitor. virtual void GetText(CefRefPtr<CefStringVisitor> visitor) =0; // Load the request represented by the |request| object. virtual void LoadRequest(CefRefPtr<CefRequest> request) =0; // Load the specified |url|. virtual void LoadURL(const CefString& url) =0; // Load the contents of |string_val| with the specified dummy |url|. |url| // should have a standard scheme (for example, http scheme) or behaviors like // link clicks and web security restrictions may not behave as expected. virtual void LoadString(const CefString& string_val, const CefString& url) =0; // Execute a string of JavaScript code in this frame. The |script_url| // parameter is the URL where the script in question can be found, if any. // The renderer may request this URL to show the developer the source of the // error. The |start_line| parameter is the base line number to use for error // reporting. virtual void ExecuteJavaScript(const CefString& code, const CefString& script_url, int start_line) =0; // Returns true if this is the main (top-level) frame. virtual bool IsMain() =0; // Returns true if this is the focused frame. virtual bool IsFocused() =0; // Returns the name for this frame. If the frame has an assigned name (for // example, set via the iframe "name" attribute) then that value will be // returned. Otherwise a unique name will be constructed based on the frame // parent hierarchy. The main (top-level) frame will always have an empty name // value. virtual CefString GetName() =0; // Returns the globally unique identifier for this frame. virtual int64 GetIdentifier() =0; // Returns the parent of this frame or NULL if this is the main (top-level) // frame. virtual CefRefPtr<CefFrame> GetParent() =0; // Returns the URL currently loaded in this frame. virtual CefString GetURL() =0; // Returns the browser that this frame belongs to. virtual CefRefPtr<CefBrowser> GetBrowser() =0; // Get the V8 context associated with the frame. This method can only be // called from the render process. virtual CefRefPtr<CefV8Context> GetV8Context() =0; // Visit the DOM document. This method can only be called from the render // process. virtual void VisitDOM(CefRefPtr<CefDOMVisitor> visitor) =0;