CEF 浏览器生命周期

浏览器生命周期从调用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<MyClient> client(new MyClient);

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

该CefLifeSpanHandler类提供了一些必要的管理浏览器寿命的回调。以下是相关方法和成员的摘录。

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

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

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

 private:
  CefRefPtr<CefBrowser> m_Browser;
  int m_BrowserId;
  int m_BrowserCount;
  bool m_bIsClosing;

  IMPLEMENT_REFCOUNTING(MyClient);
};

创建浏览器对象后,将立即调用OnAfterCreated()方法。宿主应用程序可以使用此方法来保持对主浏览器对象的引用。

void MyClient::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
  // Must be executed on the UI thread.
  REQUIRE_UI_THREAD();

  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()。

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

如果浏览器是另一个窗口的父级,则close事件可能源自该父窗口的OS功能(例如,通过单击父窗口上的X)。然后,父窗口需要调用CloseBrowser(false)并等待第二个OS关闭事件以指示浏览器已允许关闭。如果通过JavaScript“onbeforeunload”事件处理程序或DoClose()回调取消关闭,则不会发送第二个OS关闭事件。请注意以下示例中的IsClosing()检查 - 它将为第一个OS关闭事件返回false,对于第二个事件(在调用DoClose之后)返回true。

在Windows上的父窗口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;
}

处理Linux上的“delete_event”信号:

gboolean delete_event(GtkWidget * widget,GdkEvent * event,
                      GtkWindow * window){
  if(g_handler.get()&&!g_handler-> IsClosing()){
    CefRefPtr <CefBrowser> browser = g_handler-> GetBrowser();
    if(browser.get()){
      //通知浏览器窗口我们要关闭它。这将导致致电
      // MyHandler :: DoClose()如果JavaScript'onbeforeunload'事件处理程序允许它。
      浏览器的> GETHOST() - > CloseBrowser(假);

      //取消关闭
      返回TRUE;
    }
  }

  //允许关闭
  返回FALSE;
}

关闭OS X更复杂。请参阅cefsimple / cefsimple_mac.mm中的注释,以全面了解shutdown在该平台上的工作原理。

DoClose()方法设置m_bIsClosing标志并返回false以发送第二个OS关闭事件。

bool MyClient::DoClose(CefRefPtr<CefBrowser> browser) {
  // Must be executed on the UI thread.
  REQUIRE_UI_THREAD();

  // 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()) {
    // 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;
}

当OS功能接收到第二个OS关闭事件时,它允许父窗口实际关闭。然后,这会调用OnBeforeClose()。确保在OnBeforeClose()回调中释放对浏览器对象的任何引用。

void MyHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
  // Must be executed on the UI thread.
  REQUIRE_UI_THREAD();

  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();
  }
}

有关每个平台的完整工作示例,请参阅cefclient应用程序。

离屏渲染

使用屏幕外渲染CEF不会创建本机浏览器窗口。相反,CEF为主机应用程序提供无效区域和像素缓冲区,主机应用程序通知CEF鼠标,键盘和焦点事件。屏幕外渲染当前不支持加速合成,因此与窗口浏览器相比,性能可能会受到影响。屏幕外浏览器将收到与窗口浏览器相同的通知,包括上一节中描述的生命周期通知。要使用离屏渲染:

实现CefRenderHandler接口。除非另有说明,否则所有方法均需要

  • 在将CefWindowInfo结构传递给CefBrowserHost :: CreateBrowser()之前调用CefWindowInfo :: SetAsWindowless()。如果没有父窗口传递给SetAsWindowless,则某些功能(如上下文菜单)可能不可用。
  • 将调用CefRenderHandler :: GetViewRect()方法来检索所需的视图矩形。
  • 将调用CefRenderHandler :: OnPaint()方法以提供无效区域和更新的像素缓冲区。cefclient应用程序使用OpenGL绘制缓冲区,但您的应用程序可以使用您喜欢的任何技术。
  • 要调整浏览器的大小,请调用CefBrowserHost :: WasResized()。这将导致调用GetViewRect()以检索新大小,然后调用OnPaint()。
  • 调用CefBrowserHost :: SendXXX()方法以通知浏览器鼠标,键盘和焦点事件。
  • 调用CefBrowserHost :: CloseBrowser()来销毁浏览器。
    使用“—off-screen-rendering-enabled”命令行标志运行cefclient作为工作示例。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

Powered by bytekits.com,汇天下文字,成非凡梦想!!!