我在Visual Studio 2013(C ++)和Windows 8.1上测试CEF3程序。
我想处理从JavaScript调用的本机函数。但是,在执行本机功能时,浏览器会冻结。 PostTask也没有效果。
如果线程是使用CreateThread(Win32 API)创建的,则在其他线程中获取CefV8Value时会发生错误。
有没有以异步方式处理函数的好方法?
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;
}
答案 0 :(得分:4)
问题是javascript回调发生在CEF客户端的渲染过程上。该过程直接负责所有用户交互,点击,JS执行等。即使你发布到另一个帖子(在同一个过程中),它似乎没有产生巨大的差异。
您要做的是将其发送到浏览器进程并在那里进行处理。 CEF3 Faqs涵盖了此通信,以防您以前无需执行此操作:
[...] 如何在浏览器之间发送信息并在CEF3中渲染流程?
提供信息动态使用与特定
CefProcessMessage
实例关联的流程消息(CefBrowser
),并使用CefBrowser::SendProcessMessage()
方法发送。 [...]从渲染过程发送到浏览器进程的消息将到达CefClient::OnProcessMessageReceived()
。 [...]
似乎这在Adobe Brackets-Shell(一个使用CEF3的相当流行的开源WebIDE)中是一个非常大的问题 - 他们的guide to V8 extensions非常顺利。
每当调用本机函数时,都会调用
AppShellExtensionHandler::Execute()
。此代码在渲染过程中运行,因此此处只应执行最简单的扩展代码。对于括号,此处仅处理getElapsedMilliseconds()
。所有其他调用都通过CefProcessMessage
传递给浏览器进程。
此处提及的AppShellExtensionHandler
相当于您的AppExtensionHandler
。我强烈建议您通过他们的代码进行扩展处理 - 它已经非常优雅地完成了。 公平警告:虽然Brackets.io是一家开源企业,但我与Adobe有着专业的关系。
希望这会有所帮助 - 干杯!
答案 1 :(得分:2)
看一下这篇文章。它就像一个魅力。将我的所有JS解决为原生问题,并使用结构化的param传递方法......它恰好解决了你所遇到的问题......你只需要创建一个用户线程(Task)来处理后台的东西......
JS to native via V8Context - async!
我自己测试了这个并且效果非常好......我没有错过的东西......
虽然这篇文章描述了C#,但它应该非常直接地将其翻译成C ++