cef -- CefBrowserHost、Cefbwser、CefFrame

相关类说明

CefBrowserHost: 该类在浏览器窗口来看代表了 browser 进程,同时也暴露了与浏览器窗口相关的接口,该类的方法只能在 browser 进程中调用,但可以在 browser 进程的任意线程中被调用。

///
  // Create a new browser window using the window parameters specified by
  // |windowInfo|. All values will be copied internally and the actual window
  // will be created on the UI thread. If |request_context| is empty the
  // global request context will be used. This method can be called on any
  // browser process thread and will not block.
  ///
  /*--cef(optional_param=client,optional_param=url,
          optional_param=request_context)--*/
  static bool CreateBrowser(const CefWindowInfo& windowInfo,
                            CefRefPtr client,
                            const CefString& url,
                            const CefBrowserSettings& settings,
                            CefRefPtr request_context);

  ///
  // Create a new browser window using the window parameters specified by
  // |windowInfo|. If |request_context| is empty the global request context
  // will be used. This method can only be called on the browser process UI
  // thread.
  ///
  /*--cef(optional_param=client,optional_param=url,
          optional_param=request_context)--*/
  static CefRefPtr CreateBrowserSync(
      const CefWindowInfo& windowInfo,
      CefRefPtr client,
      const CefString& url,
      const CefBrowserSettings& settings,
      CefRefPtr request_context);

CefBrowser: 该类代表一个浏览器对象,在 browser 进程中该类的方法可以被任意线程调用。在 render 进程中只能在主线程被调用。

CefFrame: 表示浏览器窗口中的一个 frame,在 browser 进程中该类的方法可以被任意线程调用(简单理解就是 Frame 标识一个页面,通过该类开发者可以加载某一URL 或者一段 HTML 代码,获取页面的源码和文本,URL,V8 执行上下文,访问页面中的 DOM)

执行CefBrowserHost::CreateBrowser()创建一个browser实例,使用CefLifeSpanHandler管理browser对象生命周期。

Browser生命周期

  • Browser创建
    Browser生命周期从执行 CefBrowserHost::CreateBrowser() 或者 CefBrowserHost::CreateBrowserSync() 开始。可以在CefBrowserProcessHandler::OnContextInitialized() 回调或者特殊平台例如windows的WM_CREATE 中方便的执行业务逻辑。
// Information about the window that will be created including parenting, size, etc.
// The definition of this structure is platform-specific.

// 定义的结构体与平台相关

CefWindowInfo info;
// On Windows for example...
info.SetAsChild(parent_hwnd, client_rect);

// Customize this structure to control browser behavior.
CefBrowserSettings settings;

// CefClient implementation.
CefRefPtr client(new MyClient);

// Create the browser asynchronously. Initially loads the Google URL.
CefBrowserHost::CreateBrowser(info, client.get(), “http://www.google.com”, settings);

The CefLifeSpanHandler class provides the callbacks necessary for managing browser life span. Below is an extract of the relevant methods and members.

CefLifeSpanHandler 类提供管理 browser生合周期必需的回调。以下为相关方法和成员。

class MyClient : public CefClient,
                 public CefLifeSpanHandler,
                 ... {
  // CefClient methods.
  virtual CefRefPtr GetLifeSpanHandler() OVERRIDE {
    return this;
  }

  // CefLifeSpanHandler methods.
  void OnAfterCreated(CefRefPtr browser) OVERRIDE;
  bool DoClose(CefRefPtr browser) OVERRIDE;
  void OnBeforeClose(CefRefPtr browser) OVERRIDE;

  // Member accessors.
  CefRefPtr GetBrower() { return m_Browser; }
  bool IsClosing() { return m_bIsClosing; }

 private:
  CefRefPtr m_Browser;
  int m_BrowserId;
  int m_BrowserCount;
  bool m_bIsClosing;

  IMPLEMENT_REFCOUNTING(MyHandler);
  IMPLEMENT_LOCKING(MyHandler);
};

当browser对象创建后OnAfterCreated() 方法立即执行。宿主程序可以用这个方法来保持对browser对象的引用。

void MyClient::OnAfterCreated(CefRefPtr browser) {
  // Must be executed on the UI thread.
  REQUIRE_UI_THREAD();
  // Protect data members from access on multiple threads.
  AutoLock lock_scope(this);

  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++;
}
  • Browser销毁
    执行CefBrowserHost::CloseBrowser()销毁browser对象。

    // 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);

browser对象的关闭事件来源于他的父窗口的关闭方法(比如,在父窗口上点击X控钮。)。父窗口需要调用 CloseBrowser(false) 并且等待操作系统的第二个关闭事件来决定是否允许关闭。如果在JavaScript 'onbeforeunload'事件处理或者 DoClose()回调中取消了关闭操作,则操作系统的第二个关闭事件可能不会发送。注意一下面示例中对IsCloseing()的判断-它在第一个关闭事件中返回false,在第二个关闭事件中返回true(当 DoCloase 被调用后)。

Windows平台下,在父窗口的WndProc里处理WM_ClOSE消息:

case WM_CLOSE:
  if (g_handler.get() && !g_handler->IsClosing()) {
    CefRefPtr 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 标志位为true,并返回false以再次发送操作系统的关闭事件。

bool MyClient::DoClose(CefRefPtr 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()回调,请在该回调里释放所有对浏览器对象的引用。

void MyHandler::OnBeforeClose(CefRefPtr browser) {
  // Must be executed on the UI thread.
  REQUIRE_UI_THREAD();
  // Protect data members from access on multiple threads.
  AutoLock lock_scope(this);

  if (m_BrowserId == browser->GetIdentifier()) {
    // Free the browser pointer so that the browser can be destroyed.
    m_Browser = NULL;
  }

  if (--m_BrowserCount == 0) {
    // All browser windows have closed. Quit the application message loop.
    CefQuitMessageLoop();
  }
}

你可能感兴趣的:(cef)