在CEF里,JS和Native(C/C++)代码可以很方便的交互,这里https://bitbucket.org/chromiumembedded/cef/wiki/JavaScriptIntegration.md讲解得很清楚。我照着它实现了一个简单的交互示例。
foruok原创,如需转载请关注foruok的微信订阅号“程序视界”联系foruok。
在贴代码之前,先来看看Browser进程和Render进程是怎么回事儿,有什么不同。
Browser与Render进程
从cefsimple开始吧,cefsimple_win.cc中的wWinMain函数中调用了CefExecuteProcess()方法来检测是否要启动其它的子进程。此处的CefExecuteProcess是在libcef_dll_wrapper.cc中的,它内部又调用了cef_execute_process方法(libcef_dll.cc),cef_execute_process又调用了libcef/browser/context.cc文件内实现的CefExecuteProcess方法。这个方法代码如下:
int CefExecuteProcess(const CefMainArgs& args, CefRefPtr<CefApp> application, void* windows_sandbox_info) { base::CommandLine command_line(base::CommandLine::NO_PROGRAM);#if defined(OS_WIN) command_line.ParseFromString(::GetCommandLineW());#else command_line.InitFromArgv(args.argc, args.argv);#endif // Wait for the debugger as early in process initialization as possible. if (command_line.HasSwitch(switches::kWaitForDebugger)) base::debug::WaitForDebugger(60, true); // If no process type is specified then it represents the browser process and // we do nothing. std::string process_type = command_line.GetSwitchValueASCII(switches::kProcessType); if (process_type.empty()) return -1; CefMainDelegate main_delegate(application); // Execute the secondary process.#if defined(OS_WIN) sandbox::SandboxInterfaceInfo sandbox_info = {0}; if (windows_sandbox_info == NULL) { content::InitializeSandboxInfo(&sandbox_info); windows_sandbox_info = &sandbox_info; } content::ContentMainParams params(&main_delegate); params.instance = args.instance; params.sandbox_info = static_cast<sandbox::SandboxInterfaceInfo*>(windows_sandbox_info); return content::ContentMain(params);#else content::ContentMainParams params(&main_delegate); params.argc = args.argc; params.argv = const_cast<const char**>(args.argv); return content::ContentMain(params);#endif
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
它分析了命令行参数,提取”type”参数,如果为空,说明是Browser进程,返回-1,这样一路回溯到wWinMain方法里,然后开始创建Browser进程相关的内容。
如果”type”参数不为空,做一些判断,最后调用了content::ContentMain方法,直到这个方法结束,子进程随之结束。
content::ContentMain方法再追溯下去,就到了chromium的代码里了,在chromium/src/content/app/content_main.cc文件中。具体我们不分析了,感兴趣的可以去看看。
分析了CefExecuteProcess方法我们知道,Browser进程在cefsimple_win.cc内调用了CefExecuteProcess之后做了进一步的配置,这个是在simple_app.cc内完成的,具体就是SimpleApp::OnContextInitialized()这个方法,代码如下:
void SimpleApp::OnContextInitialized() { CEF_REQUIRE_UI_THREAD(); CefWindowInfo window_info; window_info.SetAsPopup(NULL, "cefsimple"); // SimpleHandler implements browser-level callbacks. CefRefPtr<SimpleHandler> handler(new SimpleHandler()); // Specify CEF browser settings here. CefBrowserSettings browser_settings; std::string url; CefRefPtr<CefCommandLine> command_line = CefCommandLine::GetGlobalCommandLine(); url = command_line->GetSwitchValue("url"); if (url.empty()) url = "http://www.google.com"; CefBrowserHost::CreateBrowser(window_info, handler.get(), url,