标签:iat zed ++ lease nav before using exti cal
一、Off-Screen Rendering 脱屏绘制
CEF的脱屏渲染并不创建源生的浏览器窗口,而是CEF提供主应用程序在无效区域和像素buffer里渲染,然后主应用程序通过鼠标、键盘和焦点事件通知CEF。
脱屏渲染现在不支持图层混合加速图层混合加速。脱屏渲染要窗口浏览器一样接受相同的通知,包括生命周期通知等,为了使用脱屏渲染:
二、投递任务
在单进程的不同线程之间可以通过 CefPostTask系列函数投递任务。在目标线程中,收到的任务会以异步方式在消息循环中执行。例如:
在UI线程中执行某个类方法:CefPostTask(TID_UI, NewCefRunnableMethod(object, &MyObject::MyMethod, param1, param2));
在UI线程中执行某个方法:CefPostTask(TID_IO, NewCefRunnableFunction(MyFunction, param1, param2));
如果主机应用程序需要获取运行循环的引用,可以使用CefTaskRunner类。
例如:获取线程的任务运行者:CefRefPtr<CefTaskRunner> task_runner = CefTaskRunner::GetForThread(TID_UI);
三、进程间通信
由于CEF3以多进程方式运行,需要在不同进程之间提供通信方式。CefBrowsert和CefFrame对象分别浏览进程和渲染进程,每个CefBrowser和CefFrame对象还有一个与之关联的惟一的ID值,将匹配两边边界过程
CefRefPtr<CefProcessMessage> msg= CefProcessMessage::Create(“my_message”);
// Retrieve the argument list object.
CefRefPtr<CefListValue> args = msg>GetArgumentList();
// Populate the argument values.
args->SetString(0, “my string”);
args->SetInt(0, 10);
// Send the process message to the render process.
// Use PID_BROWSER instead when sending a message to the browser process.
browser->SendProcessMessage(PID_RENDERER, msg);
从浏览进程发送的消息会到达渲染进程的 CefRenderProcessHandler::OnProcessMessageReceived()函数
从渲染进程发送的消息会到达浏览进程的CefClient::OnProcessMessageReceived()函数,如:
bool MyHandler::OnProcessMessageReceived(
CefRefPtr<CefBrowser> browser,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message) {
// Check the message name.
const std::string& message_name = message->GetName();
if (message_name == “my_message”) {
// Handle the message here...
return true;
}
return false;
}
在发送的地方使用CefFrame::GetIdentifier()函数获取窗口的唯一ID,在接受进程中获取唯一ID的窗口对象使用CefBrowser::GetFrame()函数。如:
// Helper macros for splitting and combining the int64 frame ID value. #define MAKE_INT64(int_low, int_high) ((int64) (((int) (int_low)) | ((int64) ((int) (int_high))) << 32)) #define LOW_INT(int64_val) ((int) (int64_val)) #define HIGH_INT(int64_val) ((int) (((int64) (int64_val) >> 32) & 0xFFFFFFFFL)) // Sending the frame ID. const int64 frame_id = frame->GetIdentifier(); args->SetInt(0, LOW_INT(frame_id)); args->SetInt(1, HIGH_INT(frame_id)); // Receiving the frame ID. const int64 frame_id = MAKE_INT64(args->GetInt(0), args->GetInt(1)); CefRefPtr<CefFrame> frame = browser->GetFrame(frame_id);
四、异步JavaScript绑定
JavaScript通信是在渲染进程中实现,在需要频繁的和浏览进程通信。JaveScript接口使用关闭和提示本身应该以异步方式设计。
// Create and send a new query.
var request_id = window.cefQuery({
request: ‘my_request‘,
persistent: false,
onSuccess: function(response) {},
onFailure: function(error_code, error_message) {}
});
// Optionally cancel the query.
window.cefQueryCancel(request_id);
C++处理者:class Callback : public CefBase {
public:
///
// Notify the associated JavaScript onSuccess callback that the query has
// completed successfully with the specified |response|.
///
virtual void Success(const CefString& response) =0;
///
// Notify the associated JavaScript onFailure callback that the query has
// failed with the specified |error_code| and |error_message|.
///
virtual void Failure(int error_code, const CefString& error_message) =0;
};
class Handler {
public:
///
// Executed when a new query is received. |query_id| uniquely identifies the
// query for the life span of the router. Return true to handle the query
// or false to propagate the query to other registered handlers, if any. If
// no handlers return true from this method then the query will be
// automatically canceled with an error code of -1 delivered to the
// JavaScript onFailure callback. If this method returns true then a
// Callback method must be executed either in this method or asynchronously
// to complete the query.
///
virtual bool OnQuery(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int64 query_id,
const CefString& request,
bool persistent,
CefRefPtr<Callback> callback) {
return false;
}
///
// Executed when a query has been canceled either explicitly using the
// JavaScript cancel function or implicitly due to browser destruction,
// navigation or renderer process termination. It will only be called for
// the single handler that returned true from OnQuery for the same
// |query_id|. No references to the associated Callback object should be
// kept after this method is called, nor should any Callback methods be
// executed.
///
virtual void OnQueryCanceled(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int64 query_id) {}
};
自定义实现
基于CEF的应用程序提供异步JaveScript绑定的自定义实现。简单的实现步骤如下:
在渲染进程中通过回调函数绑定JavaScript
// In JavaScript register the callback function.
app.setMessageCallback(‘binding_test‘, function(name, args) {
document.getElementById(‘result‘).value = "Response: "+args[0];
});
在渲染进程中维持回调函数中引用
// Map of message callbacks.
typedef std::map<std::pair<std::string, int>,
std::pair<CefRefPtr<CefV8Context>, CefRefPtr<CefV8Value> > >
CallbackMap;
CallbackMap callback_map_;
// In the CefV8Handler::Execute implementation for “setMessageCallback”.
if (arguments.size() == 2 && arguments[0]->IsString() &&
arguments[1]->IsFunction()) {
std::string message_name = arguments[0]->GetStringValue();
CefRefPtr<CefV8Context> context = CefV8Context::GetCurrentContext();
int browser_id = context->GetBrowser()->GetIdentifier();
callback_map_.insert(
std::make_pair(std::make_pair(message_name, browser_id),
std::make_pair(context, arguments[1])));
}
渲染过程向浏览器进程发送异步消息IPC过程要求执行工作。
// Execute the registered JavaScript callback if any.
if (!callback_map_.empty()) {
const CefString& message_name = message->GetName();
CallbackMap::const_iterator it = callback_map_.find(
std::make_pair(message_name.ToString(),
browser->GetIdentifier()));
if (it != callback_map_.end()) {
// Keep a local reference to the objects. The callback may remove itself
// from the callback map.
CefRefPtr<CefV8Context> context = it->second.first;
CefRefPtr<CefV8Value> callback = it->second.second;
// Enter the context.
context->Enter();
CefV8ValueList arguments;
// First argument is the message name.
arguments.push_back(CefV8Value::CreateString(message_name));
// Second argument is the list of message arguments.
CefRefPtr<CefListValue> list = message->GetArgumentList();
CefRefPtr<CefV8Value> args = CefV8Value::CreateArray(list->GetSize());
SetList(list, args); // Helper function to convert CefListValue to CefV8Value.
arguments.push_back(args);
// Execute the callback.
CefRefPtr<CefV8Value> retval = callback->ExecuteFunction(NULL, arguments);
if (retval.get()) {
if (retval->IsBool())
handled = retval->GetBoolValue();
}
// Exit the context.
context->Exit();
}
}
五、同步请求
在浏览进程和渲染进程中很少使用同步通信。无论什么时候应该尽可能避免使用,因为会在渲染进程中影响性能。如里实在需要同步通信可考虑使用XMLHttpRequests。
六、网络层
CEF3默认网络请求处理的方式对主机应用程序是透明的,应用程序靠近CEF3网络层的关系会更多的暴露与网络相关的功能。在不同的线程上会引用不同的网络调用。所以一定要注意文档,妥善保护您的数据成员。
七、自定义请求
在浏览进程窗口中通过CefFrame::LoadURL()函数简单的加载URL,如:browser->GetMainFrame()->LoadURL(some_url);
应用程序希望发送更多复杂的请求包含自定义请求头或者使用CefFrame::LoadRequest()函数下载数据,这个方法接受CefRequest对象作为单一参数。
// Create a CefRequest object.
CefRefPtr<CefRequest> request = CefRequest::Create();
// Set the request URL.
request->SetURL(some_url);
// Set the request method. Supported methods include GET, POST, HEAD, DELETE and PUT.
request->SetMethod(“POST”);
// Optionally specify custom headers.
CefRequest::HeaderMap headerMap;
headerMap.insert(
std::make_pair("X-My-Header", "My Header Value"));
request->SetHeaderMap(headerMap);
// Optionally specify upload content.
// The default “Content-Type” header value is "application/x-www-form-urlencoded".
// Set “Content-Type” via the HeaderMap if a different value is desired.
const std::string& upload_data = “arg1=val1&arg2=val2”;
CefRefPtr<CefPostData> postData = CefPostData::Create();
CefRefPtr<CefPostDataElement> element = CefPostDataElement::Create();
element->SetToBytes(upload_data.size(), upload_data.c_str());
postData->AddElement(element);
request->SetPostData(postData);
八、独立于浏览器的请求
应用程序可以通过CefURLRequest类发送不与某个浏览器相关联的网络请求。实现CefURLRequestClient接口以处理响应结果。
CefURLRequest可在浏览进程和渲染进程中使用。
class MyRequestClient : public CefURLRequestClient {
public:
MyRequestClient()
: upload_total_(0),
download_total_(0) {}
virtual void OnRequestComplete(CefRefPtr<CefURLRequest> request) OVERRIDE {
CefURLRequest::Status status = request->GetRequestStatus();
CefURLRequest::ErrorCode error_code = request->GetRequestError();
CefRefPtr<CefResponse> response = request->GetResponse();
// Do something with the response...
}
virtual void OnUploadProgress(CefRefPtr<CefURLRequest> request,
uint64 current,
uint64 total) OVERRIDE {
upload_total_ = total;
}
virtual void OnDownloadProgress(CefRefPtr<CefURLRequest> request,
uint64 current,
uint64 total) OVERRIDE {
download_total_ = total;
}
virtual void OnDownloadData(CefRefPtr<CefURLRequest> request,
const void* data,
size_t data_length) OVERRIDE {
download_data_ += std::string(static_cast<const char*>(data), data_length);
}
private:
uint64 upload_total_;
uint64 download_total_;
std::string download_data_;
private:
IMPLEMENT_REFCOUNTING(MyRequestClient);
};
发送请求:
// Set up the CefRequest object.
CefRefPtr<CefRequest> request = CefRequest::Create();
// Populate |request| as shown above...
// Create the client instance.
CefRefPtr<MyRequestClient> client = new MyRequestClient();
// Start the request. MyRequestClient callbacks will be executed asynchronously.
CefRefPtr<CefURLRequest> url_request = CefURLRequest::Create(request, client.get());
// To cancel the request: url_request->Cancel();
CefURLRequest制定的请求还可以通过CefRequest::SetFlags()函数指定自定义行为:
UR_FLAG_SKIP_CACHE 当处理请求时,如果设置了缓存就跳过。
UR_FLAG_ALLOW_CACHED_CREDENTIALS 如果设置cookie可以发送请求和保存从响应。此必须被设置
UR_FLAG_REPORT_UPLOAD_PROGRESS 如果设置上载过程事件时将产生当请求体时。
UR_FLAG_REPORT_LOAD_TIMING 如里设置加载时间信息在请求时会被收集。
UR_FLAG_REPORT_RAW_HEADERS 如果设置头信息发送和接收的请求将被记录下来。
UR_FLAG_NO_DOWNLOAD_DATA 如里设置了,CefURLRequestClient::OnDownloadData方法不会被调用。
UR_FLAG_NO_RETRY_ON_5XX 如果设置5 xx重定向错误将被传递到观察者,而不是自动重试。这个目前仅适用于来自浏览器的请求过程。
如:request->SetFlags(UR_FLAG_SKIP_CACHE | UR_FLAG_NO_DOWNLOAD_DATA);
九、请求处理
在应用程序中CEF3支持两种方法来处理网络请求。计划处理程序方法允许注册的处理程序请求针对一个特定的起源(方案+域),请求拦截方法允许任意请求的处理在应用程序自由裁量权。使用HTTP方案而不是定制的方案,以避免一系列潜在问题。
如果选择使用自定义方案,你必须向CEF注册,如果想自定义方案有HTTP相同的行为,那么应该想标准方案一样注册。如果打算执行跨域请求其他方案或通过XMLHttpRequst发送POST请求到自定义方案中处理,那么应用使用HTTP方案来代替自定义方案以避免潜在的问题。哪里希望自定义属性通过cefApp::OnRegisterCustomSchemes()回调函数注册并在所有进程中实现。
void MyApp::OnRegisterCustomSchemes(CefRefPtr<CefSchemeRegistrar> registrar)
{ // Register "client" as a standard scheme.
registrar->AddCustomScheme("client", true, false, false);
}
十、Scheme Handler
Scheme Handler通过CefRegisterSchemeHandlerFactory()函数注册,CefBrowserProcessHandler::OnContextInitialized()是此函数的最好调用的地方。
CefRegisterSchemeHandlerFactory("client", “myapp”, new MySchemeHandlerFactory());
Handler是用在内置方案和自定义方案。当使用内置方案时选择一个域名唯一标识应用程序。实现CefSchemeHandlerFactory和CefResourceHandler类处理请求和提供响应数据。如果使用自定义方案不要忘记实现CefApp::OnRegisterCustomSchemes函数。
十一、请求拦截
CefRequestHandler::GetResourceHandler()函数支持任意请求的拦截。使用与CefResourceHandler同样的类处理方法。如果使用自定义方案不要忘记使用 CefApp::OnRegisterCustomSchemes函数。
十二、Other Callbacks
CefRequestHandler接口处理各种各样的与网络相关的事件,包括认证、cookie处理、扩展协议、证书错误处理等等
标签:iat zed ++ lease nav before using exti cal
原文地址:http://www.cnblogs.com/h2zZhou/p/6871895.html