CEF系列技术文章:从零开始构建AI浏览器
概述
CEF(Chromium Embedded Framework)是一个开源框架,用于将基于Chromium的浏览器嵌入到其他应用程序中。本文将结合实际AI浏览器开发经验,详细介绍CEF的核心技术点,包括启动流程、UI定制、Schema自定义、菜单定制以及项目编译等。
CEF启动流程
CEF应用程序的启动遵循一个标准化的流程,主要包含以下几个关键步骤:
1. 进程执行检查
CEF应用程序支持多进程架构,首先需要检查当前进程类型:
// 提供CEF命令行参数
CefMainArgs main_args(hInstance);
// 检查是否为子进程,如果是则执行相应逻辑
exit_code = CefExecuteProcess(main_args, nullptr, sandbox_info);
if (exit_code >= 0) {
return exit_code; // 子进程完成
}
2. CEF初始化
浏览器进程需要初始化CEF:
// 配置CEF设置
CefSettings settings;
if (!sandbox_info) {
settings.no_sandbox = true;
}
// 创建应用程序实例
CefRefPtr<SimpleApp> app(new SimpleApp);
// 初始化CEF浏览器进程
if (!CefInitialize(main_args, settings, app.get(), sandbox_info)) {
return CefGetExitCode();
}
3. 消息循环运行
// 运行CEF消息循环,会阻塞直到调用CefQuitMessageLoop()
CefRunMessageLoop();
// 关闭CEF
CefShutdown();
CEF应用程序架构
CEF通过CefApp接口提供应用程序级别的回调:
class CefApp : public virtual CefBaseRefCounted {
public:
// 在CEF处理命令行参数前提供修改机会
virtual void OnBeforeCommandLineProcessing(
const CefString& process_type,
CefRefPtr<CefCommandLine> command_line) {}
// 注册自定义协议
virtual void OnRegisterCustomSchemes(
CefRawPtr<CefSchemeRegistrar> registrar) {}
};
Chrome模式UI展示
CEF支持两种主要的UI模式:标准模式和Chrome模式。Chrome模式提供完整的浏览器界面,包括地址栏、标签页、工具栏等。
Chrome集成架构
CEF通过ChromeBrowserDelegate类与Chrome浏览器架构集成:
class ChromeBrowserDelegate : public cef::BrowserDelegate {
public:
ChromeBrowserDelegate(Browser* browser,
const CefBrowserCreateParams& create_params,
const Browser* opener);
// 处理浏览器命令
bool HandleCommand(int command_id,
WindowOpenDisposition disposition) override;
// 控制应用菜单项可见性
bool IsAppMenuItemVisible(int command_id) override;
};
自定义Schema实现
在AI浏览器开发中,我们通过自定义appcontent://协议来实现HTML自定义首页。
1. 注册自定义协议
在CefApp::OnRegisterCustomSchemes中注册:
void MyApp::OnRegisterCustomSchemes(
CefRawPtr<CefSchemeRegistrar> registrar) {
// 注册appcontent协议
registrar->AddCustomScheme("appcontent",
CEF_SCHEME_OPTION_STANDARD | CEF_SCHEME_OPTION_CORS_ENABLED);
}
2. 处理自定义协议请求
通过CefRequestHandler处理自定义协议请求:
bool MyApp::OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback) {
std::string url = request->GetURL();
if (url.find("appcontent://") == 0) {
// 返回自定义HTML内容
CefRefPtr<CefStreamReader> stream = GetCustomContentStream(url);
request->SetURL(stream->GetUrl());
}
return false;
}
菜单定制
CEF提供了灵活的菜单定制机制,可以隐藏Chromium默认菜单并添加自定义菜单项。
1. 上下文菜单定制
通过实现CefContextMenuHandler:
void ClientHandler::OnBeforeContextMenu(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefContextMenuParams> params,
CefRefPtr<CefMenuModel> model) {
// 清除默认菜单项
model->Clear();
// 添加自定义菜单项
model->AddItem(MENU_ID_AI_CHAT, "AI助手");
model->AddItem(MENU_ID_TRANSLATE, "页面翻译");
model->AddSeparator();
model->AddItem(MENU_ID_SETTINGS, "设置");
}
2. Chrome应用菜单定制
CEF通过补丁修改Chrome的菜单系统:
// 注册菜单创建回调
void RenderViewContextMenu::RegisterMenuCreatedCallback(
MenuCreatedCallback cb) {
*GetMenuCreatedCallback() = cb;
}
// 注册菜单显示处理回调
void RenderViewContextMenu::RegisterMenuShowHandlerCallback(
MenuShowHandlerCallback cb) {
*GetMenuShowHandlerCallback() = cb;
}
项目集成与编译
CMake集成
CEF提供了完整的CMake支持,通过模板文件生成项目配置:
# 设置CEF根目录
set(CEF_ROOT "${CMAKE_CURRENT_SOURCE_DIR}")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CEF_ROOT}/cmake")
# 查找CEF包
find_package(CEF REQUIRED)
# 添加libcef_dll_wrapper目标
add_subdirectory(${CEF_LIBCEF_DLL_WRAPPER_PATH} libcef_dll_wrapper)
# 添加应用程序目标
add_subdirectory(tests/cefclient)
构建配置
CEF支持多种构建配置:
# Windows 64位构建
cmake -G "Visual Studio 17" -A x64 ..
# macOS构建
cmake -G "Xcode" -DPROJECT_ARCH="arm64" -DCMAKE_BUILD_TYPE=Debug ..
# Linux构建
cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Debug ..
实战案例:AI浏览器开发
基于CEF开发AI浏览器的核心实现:
1. 应用程序结构
class AIBrowserApp : public CefApp,
public CefBrowserProcessHandler {
public:
// 注册自定义协议
void OnRegisterCustomSchemes(
CefRawPtr<CefSchemeRegistrar> registrar) override {
registrar->AddCustomScheme("appcontent",
CEF_SCHEME_OPTION_STANDARD);
}
// 获取浏览器进程处理器
CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() override {
return this;
}
// 上下文初始化后创建浏览器
void OnContextInitialized() override {
// 创建AI浏览器主窗口
CreateAIBrowserWindow();
}
};
2. AI功能集成
class AIBrowserHandler : public CefDisplayHandler,
public CefContextMenuHandler {
public:
// 页面加载完成后注入AI功能
void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
bool isLoading,
bool canGoBack,
bool canGoForward) override {
if (!isLoading) {
// 注入AI助手脚本
InjectAIScript(browser);
}
}
// 自定义右键菜单
void OnBeforeContextMenu(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefContextMenuParams> params,
CefRefPtr<CefMenuModel> model) override {
model->Clear();
model->AddItem(MENU_AI_SUMMARIZE, "AI总结");
model->AddItem(MENU_AI_EXPLAIN, "AI解释");
}
};
3. 云编译优化
对于大型CEF项目,避免不了需要修改CEF和Chromium,建议使用云编译环境:
- 并行构建:使用Ninja构建系统支持并行编译
- 缓存优化:配置ccache加速重复编译
- 分布式编译:使用distcc实现多机器编译
# 云编译命令示例
cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache ..
ninja -j$(nproc) cefclient
修改CEF源码重新编译需要比较长的时间,我在的Intel Ultra 5机器上8小时才完成编译,建议使用云电脑或者云服务器上进行编译。
最近天翼云电脑在免费赠送高配云电脑,可免费使用两个月,已实名的三网手机号,即可扫码领取8C16G精英版云电脑:

总结
CEF为开发者提供了强大的浏览器嵌入能力,通过合理利用其架构特性,可以快速构建功能丰富的AI浏览器应用。关键技术点包括:
- 掌握CEF的多进程启动流程
- 利用Chrome模式提供完整浏览器体验
- 通过自定义Schema实现灵活的内容定制
- 灵活的菜单定制机制满足个性化需求
- 完善的CMake集成支持跨平台开发
实际效果:


在实际开发中,建议参考CEF提供的示例项目(cefclient、cefsimple),逐步构建自己的AI浏览器应用。

浙公网安备 33010602011771号