Javascript Chromium嵌入式框架中本机函数的后台处理
我正在Visual Studio 2013(C++)和Windows 8.1上测试CEF3程序 我想处理从JavaScript调用的本机函数。但是,在执行本机函数时,浏览器会冻结。PostTask也无效 在使用CreateThread(Win32 API)创建线程的情况下,在另一个线程中获取CefV8Value时会发生错误 异步处理函数没有什么好方法吗Javascript Chromium嵌入式框架中本机函数的后台处理,javascript,c++,multithreading,chromium,chromium-embedded,Javascript,C++,Multithreading,Chromium,Chromium Embedded,我正在Visual Studio 2013(C++)和Windows 8.1上测试CEF3程序 我想处理从JavaScript调用的本机函数。但是,在执行本机函数时,浏览器会冻结。PostTask也无效 在使用CreateThread(Win32 API)创建线程的情况下,在另一个线程中获取CefV8Value时会发生错误 异步处理函数没有什么好方法吗 CefSettings settings; settings.single_process = true; void App::OnConte
CefSettings settings;
settings.single_process = true;
void App::OnContextCreated(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context)
{
CoInitializeEx(NULL, COINIT_MULTITHREADED);
// Retrieve the context's window object.
CefRefPtr<CefV8Value> object = context->GetGlobal();
CefRefPtr<CefV8Handler> handler = new AppExtensionHandler(this);
object->SetValue("execNative",
CefV8Value::CreateFunction("execNative", handler),
V8_PROPERTY_ATTRIBUTE_NONE);
}
bool AppExtensionHandler::Execute(const CefString& name,
CefRefPtr<CefV8Value> object,
const CefV8ValueList& arguments,
CefRefPtr<CefV8Value>& retval,
CefString& exception)
{
CefRefPtr<CefBrowser> browser = CefV8Context::GetCurrentContext()->GetBrowser();
if (!browser.get()) return false;
if (name == "execNative") {
Sleep(10000); // heavy process
CefRefPtr<CefFrame> frame = browser->GetMainFrame();
frame->ExecuteJavaScript(L"result(true)", frame->GetURL(), 0);
}
return true;
}
cef设置;
settings.single_process=true;
void应用程序::OnContextCreated(
CefRefPtr浏览器,
CefRefPtr框架,
CefRefPtr(上下文)
{
CoInitializeX(空,Conit_多线程);
//检索上下文的窗口对象。
cefreftr object=context->GetGlobal();
CefRefPtr handler=新AppExtensionHandler(此);
对象->设置值(“execNative”,
CefV8Value::CreateFunction(“execNative”,处理程序),
V8_属性_属性_无);
}
bool AppExtensionHandler::Execute(常量字符串和名称,
CefRefPtr对象,
常量cefv8值列表和参数,
Cefreftr&retval,
(字符串和异常)
{
CefRefPtr browser=CEFW8Context::GetCurrentContext()->GetBrowser();
如果(!browser.get())返回false;
如果(名称==“execNative”){
睡眠(10000);//沉重的过程
CefRefPtr frame=browser->GetMainFrame();
frame->ExecuteJavaScript(L“result(true)”,frame->GetURL(),0);
}
返回true;
}
问题在于javascript回调发生在CEF客户端的呈现过程中。这个过程直接负责所有用户交互、点击、JS执行等。即使你发布到另一个线程(在同一个过程中),看起来也没有什么大区别
您要做的是将其发送到浏览器进程并在那里进行处理。如果您以前不需要这样做,本手册将涵盖此通信:
[…]如何在CEF3中的浏览器和渲染进程之间发送信息?
要动态提供信息,请使用流程消息(CefProcessMessage
),这些消息与特定的CefBrowser
实例关联,并使用CefBrowser::SendProcessMessage()
方法发送。[…]从渲染进程发送到浏览器进程的消息将到达CefClient::OnProcessMessageReceived()
。[……]
在AdobeShell(一个使用CEF3的相当流行的开源WebIDE)中,这似乎是一个相当大的问题——他们的开发过程非常顺利
无论何时调用本机函数,都会调用AppShellExtensionHandler::Execute()。这段代码在渲染过程中运行,因此这里只执行最简单的扩展代码。对于方括号,此处仅处理getElapsedMilliseconds()
。所有其他调用都通过CefProcessMessage
传递到浏览器进程
这里提到的AppShellExtensionHandler
相当于您的AppExtensionHandler
。我强烈建议您仔细阅读他们的扩展处理代码——这是非常优雅的。公平的警告:我与Adobe有专业关系,尽管bracts.io是一家开源企业
希望这有帮助-干杯 看看这篇文章。它就像一个符咒。解决了我所有的JS到本机的问题,并使用了结构化的参数传递方法。它也正好解决了您遇到的问题。。。你只需要创建一个用户线程(任务)来处理后台的事情 我自己测试过,效果很好除非我遗漏了什么
虽然这篇文章描述了C#但将其翻译成C++应该很简单谢谢你的详细描述。如果OnProcessMessageReceived中存在大量处理,浏览器将冻结。我将通过使用CreateThread将CefV8Value更改为静态值来解决这个问题。