cef在android中使用_使用CEF类库处理HTTP请求

本文介绍了在基于CEF开发Android应用时如何使用CEF库处理HTTP请求,包括构造CefRequest对象、实现CefURLRequestClient接口来处理响应,以及创建和执行URL请求的方法。
摘要由CSDN通过智能技术生成

当我们基于CEF开发应用时,可能会有URL请求处理的需求,比如HTTP下载或上传,此时可以利用CEF提供的类库来完成,而不必自己实现或引入其它第三方的类库。

在CEF里为URL Request设计了两组类,一组用于执行网络请求,一组代表请求数据。

foruok原创,转载请保留出处或关注foruok的微信订阅号“程序视界”来联系foruok。

URLRequest

CefURLRequest是执行URL请求的类(接口),对应的头文件是cef_urlrequest.h,实现则在libcef/common/urlrequest_impl.cc文件中。

CefURLRequest类的静态方法Create()可以创建并执行一个URL请求。它的原型如下:

static CefRefPtr Create(

CefRefPtr request,

CefRefPtr client,

CefRefPtr request_context);

第一个参数,类型是CefRequest,代表一个URL请求,CEF库内部已经实现了,后面会讲到。

第二个参数,类型是CefURLRequestClient,用于接收服务器返回的状态和数据,需要我们自己继承CefURLRequestClient接口实现一个非抽象类。后面有了。

第三个参数,CefRequestContext,为NULL时内部会自己创建一个合适的Context,不为NULL时就用传入的Context。

Create方法会根据当前是Browser进程还是Renderer进程来创建对应的URLRequest类,CefBrowserURLRequest(browser_urlrequest_impl.h/.cc)或CefRenderURLRequest(render_urlrequest_impl.h/.cc)。

这么分析下来,我们要进行URL请求,实际上要做的工作就是:

构造一个CefRequest,代表我们的请求

写一个类实现CefURLRequestClient接口来处理响应。

调用CefURLRequest::Create()创建一个URL请求处理对象

构造Request

CefRequest类代表了一个URL请求,它里面可以配置方法、URL、头部、上传的数据等。下面的代码片段演示了如何构造一个 CefRequest 对象:

CefRefPtr data = CefPostData::Create();

CefRefPtr element = CefPostDataElement::Create();

const char szData[] = "Hello World!";

element->SetToBytes(sizeof(szData) - 1, (const void*)szData);

data->AddElement(element);

CefRequest::HeaderMap headers;

headers.insert(std::make_pair("Content-Type", "text/plain"));

headers.insert(std::make_pair("Accept", "text/plain"));

CefRefPtr req = CefRequest::Create();

req->SetMethod("POST");

req->SetURL("http://xxx.net");

req->SetHeaderMap(headers);

req->SetPostData(data);

与一个请求相关的类和接口,都在cef_request.h中,实现在request_impl.cc中。这些类都有静态的Create方法,可以返回一个代表具体实例的接口,然后就可以接口的方法来定制实例对象,定制后的对象就可以用于URL请求了。

刚才的代码片段演示了如何构造一个CefRequest对象,其中用到了下面的类(接口):

CefRequest,代表了一个URL请求

CefPostData,管理要通过请求发送的数据,它内部维护了多个CefPostDataElement,每个CefPostDataElement代表了一个要发送的数据元素

CefPostDataElement,代表发送的数据,提供了一些接口,可以关联到文件,也可以直接发送字节

想了解至于这些类的接口,打开头文件看看吧。

实现CefURLRequestClient接口

CefURLRequestClient接口的实现可以很简单,我实现了一个简单的UrlRequestClient类。

UrlRequestClient.h如下:

#ifndef URL_REQUEST_CLIENT_H

#define URL_REQUEST_CLIENT_H

#include

#include "include/cef_urlrequest.h"

#include "include/wrapper/cef_helpers.h"

class UrlRequestCompletionCallback

{

public:

virtual ~UrlRequestCompletionCallback(){}

virtual void OnCompletion(CefURLRequest::ErrorCode errorCode,

const std::string& data) = 0;

};

class UrlRequestClient : public CefURLRequestClient

{

public:

UrlRequestClient()

: m_callback(0)

{

CEF_REQUIRE_UI_THREAD();

}

UrlRequestClient(UrlRequestCompletionCallback *callback)

: m_callback(callback)

{

CEF_REQUIRE_UI_THREAD();

}

//

//interfaces of CefURLRequestClient

//

void OnRequestComplete(CefRefPtr request) OVERRIDE;

void OnUploadProgress(CefRefPtr request,

int64 current,

int64 total) OVERRIDE;

void OnDownloadProgress(CefRefPtr request,

int64 current,

int64 total) OVERRIDE;

void OnDownloadData(CefRefPtr request,

const void* data,

size_t data_length) OVERRIDE;

bool GetAuthCredentials(bool isProxy,

const CefString& host,

int port,

const CefString& realm,

const CefString& scheme,

CefRefPtr callback) OVERRIDE{

return false;

}

void Request(CefRefPtr cef_request);

void Get(const std::string &url, const CefRequest::HeaderMap &headers = CefRequest::HeaderMap());

void Post(const std::string &url, const CefRefPtr data, const CefRequest::HeaderMap &headers = CefRequest::HeaderMap());

void SetCompletionCallback(UrlRequestCompletionCallback *callback)

{

m_callback = callback;

}

private:

UrlRequestCompletionCallback *m_callback;

CefRefPtr m_urlRequest;

std::string m_data;

IMPLEMENT_REFCOUNTING(UrlRequestClient);

DISALLOW_COPY_AND_ASSIGN(UrlRequestClient);

};

class PrintUrlReqCallback : public UrlRequestCompletionCallback

{

public:

void OnCompletion(CefURLRequest::ErrorCode errorCode, const std::string& data);

};

#endif

UrlRequestClient.cpp内容如下:

#include "UrlRequestClient.h"

#include

void UrlRequestClient::OnRequestComplete(CefRefPtr request)

{

CEF_REQUIRE_UI_THREAD();

if (m_callback) {

m_callback->OnCompletion(request->GetRequestError(), m_data);

}

}

void UrlRequestClient::OnUploadProgress(CefRefPtr request, int64 current, int64 total)

{

}

void UrlRequestClient::OnDownloadProgress(CefRefPtr request, int64 current, int64 total)

{

char szLog[128] = { 0 };

sprintf_s(szLog, 128, "UrlRequestClient::OnDownloadProgress, current-%lld, total-%lld\r\n",

current, total);

OutputDebugStringA(szLog);

}

void UrlRequestClient::OnDownloadData(CefRefPtr request, const void* data, size_t data_length)

{

m_data += std::string(static_cast(data), data_length);

}

void UrlRequestClient::Request(CefRefPtr cef_request)

{

m_urlRequest = CefURLRequest::Create(cef_request, this, NULL);

}

void UrlRequestClient::Get(const std::string &url, const CefRequest::HeaderMap &headers /*= CefRequest::HeaderMap()*/)

{

CefRefPtr req = CefRequest::Create();

req->SetURL(url);

req->SetMethod("GET");

req->SetHeaderMap(headers);

Request(req);

}

void UrlRequestClient::Post(const std::string &url, const CefRefPtr data, const CefRequest::HeaderMap &headers /*= CefRequest::HeaderMap()*/)

{

CefRefPtr req = CefRequest::Create();

req->SetURL(url);

req->SetMethod("POST");

req->SetHeaderMap(headers);

req->SetPostData(data);

Request(req);

}

//

// for test

//

void PrintUrlReqCallback::OnCompletion(CefURLRequest::ErrorCode errorCode, const std::string& data)

{

char szLog[128] = { 0 };

sprintf_s(szLog, 128, "PrintUrlReqCallback::OnCompletion, errorCode = %d, data.len = %d, data:\r\n",

errorCode, data.length());

OutputDebugStringA(szLog);

delete this;

}

UrlRequestClient类可以发起URL请求并处理响应。它的用法类似下面这样(注意要在Browser进程的UI线程使用):

// Get() test

UrlRequestClient *client = new UrlRequestClient(new PrintUrlReqCallback);

std::string url("http://www.baidu.com");

client->Get(url);

// Request() test

CefRefPtr req = CefRequest::Create();

req->SetMethod("GET");

req->SetURL("http://www.csdn.net");

CefRequest::HeaderMap headers;

headers.insert(std::make_pair("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"));

headers.insert(std::make_pair("Accept-Encoding", "gzip,deflate,sdch"));

headers.insert(std::make_pair("Accept-Language", "en,zh"));

req->SetHeaderMap(headers);

(new UrlRequestClient(new PrintUrlReqCallback))->Request(req);

// Post() test

CefRefPtr data = CefPostData::Create();

CefRefPtr element = CefPostDataElement::Create();

const char szData[] = "Hello World!";

element->SetToBytes(sizeof(szData) - 1, (const void*)szData);

data->AddElement(element);

CefRequest::HeaderMap headers;

headers.insert(std::make_pair("Content-Type", "text/plain"));

headers.insert(std::make_pair("Accept", "text/plain"));

(new UrlRequestClient(new PrintUrlReqCallback))->Post("http://xxx.com/hello", data, headers);

就这样吧。

关于CEF里的线程,可以参考:http://blog.csdn.net/foruok/article/details/50674141。

关于进程,可以参考:http://blog.csdn.net/foruok/article/details/50621751。

其他参考文章详见我的专栏:【CEF与PPAPI开发】。

————————————————

版权声明:本文为CSDN博主「foruok」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/foruok/article/details/50679694

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值