999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

CEF應用與交互研究

2021-04-20 06:34:22付莎
電子技術與軟件工程 2021年3期
關鍵詞:進程定義

付莎

(云南省少數民族語文指導工作委員會辦公室 云南省昆明市 650021)

傳統軟件開發C/S、B/S 模式各有利弊。C/S 模式可控性、定制性高,但技術門檻高、開發周期長、綜合成本大。B/S 模式技術門檻稍低,開發周期相對較短,構建UI 交互高效快捷。但B/S 模式也因受限瀏覽器限制,在一些需要和操作系統、硬件設備等底層進行數據交互時近乎無能為力。復雜UI 交互如使用C/S 模式則需要花費大量時間精力且未必能達到B/S 模式效果。

CEF(Chromium Embedded Framework)是一套基于Google Chromium 的BSD 協議開源跨平臺項目。通過CEF 提供的接口,第三方應用程序可方便、高效的將Google Chromium 集成進自己的項目[3]。

通過CEF 的嵌入使用,應用程序可使用現代化的Web 技術快速、高效的構建應用程序UI 交互。而少部分其他需要和操作系統、第三方API 或硬件設備等底層進行交互的功能模塊又可全部交由原生軟件完成。并通過CEF 相關接口和Web UI 進行數據交互。

使用CEF 可使應用系統構建為一種混合模式。大量的UI 交互使用Web 技術完成。而不可以使用Web 技術完成的或使用Web 構建較為復雜的以及使用Web 效率低下的部分則可使用原生C++編寫完成。可充分最大化C/S 和B/S 模式的各自優勢。使軟件系統開發效率高效、而成本低廉。

最近幾年隨著Google Chromium 項目和計算機硬件的不斷發展,混合模式的開發優勢逐漸凸顯。獲得了大量行業龍頭企業的認可與應用。例如騰訊QQ、微信PC 版、網易云音樂、阿里旺旺、阿里釘釘等都使用了CEF 技術或基于CEF 的深度訂制技術。

1 CEF簡介

CEF 是一套基于Google Chromium[6]項目的開源嵌入式框架。隨著Google Chromium 項目的推進,其一開始使用的WebKit 內核被新的Blink 內核取代[1],并推出了全新的Chromium content API。新版增強了對HTML5 和GPU 硬件加速的支持,機制更現代化,極大改進了瀏覽器性能和穩定性。但隨之而來的是原有底層結構大幅改動,因此CEF 也隨content API 推出了全新版本:CEF3。原版本改名為CEF1。因此現今一般CEF 特指CEF3 版本。本文所述也特指CEF3 版本[3]。

Google Chromium 采用C++語言編寫。由于功能強大與技術先進,代碼量極其龐大和復雜,擴展及二次開發極為困難[5]。直接使用Chromium 源碼進行集成使用極為復雜,學習與使用成本高昂,一般開發人員掌握、使用都非常困難[4]。CEF 使用C++語言對Chromium 公共接口進行了重新封裝。對大量的 Chromium 接口進行了默認實現,隔離了Chromium 極為龐大的源碼與具體實現。提供了新的易于使用的對外接口。第三方嵌入時只需使用CEF 接口提供的默認實現,并通過少量的代碼編寫即可將 Chromium 嵌入第三方應用使用。

2 CEF構架與主要對外接口

CEF 是多進程模型。在CEF 構架中定義了Broswer 和Render兩種不同類型的進程。Browser 進程負責UI 部分的窗口管理、界面繪制和相關網絡傳輸。Render 進程負責Blink 內核的渲染和JavaScript 執行。嵌入使用時主應用程序的一些應用邏輯例如:JavaScript 綁定、DOM 節點的訪問等也在Render 進行中執行。默認的進程模型中,會為每個頁面創建一個新的Render 進程。進程之間通過IPC 進行通信。Browser 和Render 進程可以通過發送異步消息進行雙向通信[2]。

CEF 提供了libcef_dll_wrapper 工程導出了相關C++接口。使用時只需使用此包裝接口即可快速集成CEF 到第三方主應用程序,從而隔絕了Chromium 的復雜接口。以下CEF 主要C++接口均來自libcef_dll_wrapper 工程包的導出。

CefBrowser 對象代表當前的瀏覽器窗口。通過CefBrowser 對象可以獲取當前Browser 的各項信息,并對Browser 進行特定操作。例如操作Browser 打開頁面、回退、強制刷新當前頁面等。

CefFrame 對象代表Broswer 下的Frames。每個CefBrowser 對象包含一個主CefFrame 對象,主CefFrame 對象代表Web 頁面的頂層frame。Browser 對象下可以包含零個或多個的CefFrame 對象,分別代表不同的子Frame。獲取Frame 對象后可對Frame 進行特定的操作。例如當前Frame 下的源碼獲取、DOM 獲取、Frame 內容拷貝以及當前Frame 執行JavaScript 語句等。

CefClient 接口提供訪問瀏覽器實例的回調接口。瀏覽器實例的相關各種控制:例如自定義處理瀏覽器的生命周期、右鍵菜單、下載處理、對話框、通知顯示、拖曳事件、焦點事件、鍵盤事件等,都必須通過CefClient 接口相應方法指定處理handler。一個CefClient 對象實現可以在任意數量的Browser 進程中共享。

CefBrowserProcessHandler 接口對應Browser 進程的回調。可用于在Browser 創建時進行一些特定的初始化。

CefRenderProcessHandler 接口對應Render 進程的回調。自定義的一些應用邏輯:例如JavaScript 綁定、擴展等需要在此接口實現。

CefApp 接口提供訪問進程相關的回調。包括代碼化設置啟動參數、自定義請求頭部、設置Browser 和Render 進程處理Handler。一些特殊的設置,例如開始攝像頭支持、允許使用Flash、關閉同源策略、允許訪問本機文件等都可在CefApp 提供的接口中設置。初始化CEF 函數CefInitialize 需提供此接口的實例。必須實現。

CefLifeSpanHandler 接口提供管理Browser 生命周期回調。

CefV8Handler 用于實現自注冊的JS 函數處理邏輯。當我們在CefRenderProcessHandler 接口上注冊了自定義函數或對象,在Web端執行相應的JS 代碼時,將會調用本接口的Execute 方法。

CefSettings 對象用于定義全局的CEF 配置項。例如是否使用Cookie 緩存、日志輸出、定義當前語言、遠程調試端口等。

CefString CEF 由于跨平臺和不同運行時編譯等原因提供了統一的字符串管理,提供統一的內存堆管理、支持UTF8,UTF16 等字符串類型,為CEF 字符串定義了自己的數據結構。在使用CEF 的過程中所有使用字符串的地方都需要使用CefString 結構。

CefInitialize 函數用于在主應用程序中初始化CEF Broswer 進程。

CefShutdown 函數用于在主應用程序中關閉使CEF 停止工作。

3 宿主應用程序結構

使用CEF 時,宿主應用程序據結構應按下述步驟構建才能使CEF 正常工作,主要有以下四個步驟[2]:

(1)提供CefApp 的實現,用于處理CEF 所需的進程相關的回調。

定義CCefClientApp 類。繼承于CefApp、CefBrowserProcess Handler 以及CefRenderProcessHandler。實現OnBeforeCommandLine Processing、GetBrowserProcessHandler 與GetRenderProcessHandler三個主要回調。主要用于參數設置。定義Browser 與Render 進程回調處理。

(2)提供CefClient 的實現,用于處理CEF 所需的Browser 實例相關的回調。

定義CCefClientHandler 類。繼承于CefClient 與CefLifeSpan Handler。實現GetDisplayHandler、GetLifeSpanHandler、GetLoad Handler、OnProcessMessageReceived 以及OnAfterCreated、DoClose、OnBeforeClose。定義Brower 實例的各相關回調。

(3)在CefClient 實現中使用CEF 提供的CefBrowserHost::CreateBrowser()函數創建一個Browser 實例。

在CCefClientHandler 類中定義CreateBrowser 函數。使用靜態函數CefBrowserHost::CreateBrowser()創建Browser 實例。當宿主應用程序窗口創建時,調用CreateBrowser 函數創建Browser 實例窗口。

(4)使用CefInitialize 初始化CEF。

在宿主應用程序入口處,使用CefInitialize 函數,傳入上述定義的CCefClientApp 對象作為啟動參數啟動CEF。

在實現上述四個步驟的相關定義后,即可在宿主應用程序中嵌入CEF。由于使用了CEF 的預制默認實現,上述大部分實現函數只需直接return this;即可啟動CEF。實現了方便、簡單的嵌入使用。

4 CEF下C++與JavaScript 相互交互

CEF 的嵌入使用最為關鍵的一項技術應用即為構建的Web 頁面怎么樣和原生C++程序相互交互。只有C++與JS 語言之間能實現數據相互交互、協助運行,本文所述的混合模式、CEF 的嵌入使用才能發揮最大的作用。

C++調用JavaScript:

C++調用執行JavaScript 相對簡單。通過CefBrowser 獲取包含的CefFrame 對象,執行CefFrame 對象方法ExecuteJavaScript()函數即可實現C++調用JavaScript。該函數在Browser 與Render 進程均可調用。需要注意的是ExecuteJavaScript 不支持JS 處理結果返回[7]。

JavaScript 調用C++:

(1)CEF 窗口綁定。允許C++將變量、對象或函數附加到一個Frame 的window 對象上,供JavaScript 端調用。窗口綁定需在CefRenderProcessHandler::OnContextCreated() 方法中實現并使用CefV8Value::SetValue 函數添加到上下文中,即上述CCefClientApp類中實現OnContextCreated 方法。可針對不同的Frame 設置同一個對象不同的值。

(2)CEF 擴展。與窗口綁定類似,區別是擴展將變量、對象或函數附加到特定對象上,非窗口綁定的window 對象。擴展將加載到所有Frame 對象上,且不能修改其值。擴展需在Ce fRenderProcessHandler::OnWebKitInitialized() 方法中實現,即上述CCefClientApp 類中實現OnWebKitInitialized 方法,并使用CefRegisterExtension 函數注冊。

當JS 需要調用C++函數代碼時,一般處理方式為:首先將函數在CefV8Handler::Execute()方法中實現,然后使用以上兩種方式之一注冊對應函數。當JS 調用相應函數時,將會觸發CefV8Handler::Execute()方法[8]。

5 Windows下CEF應用實例

本實例將演示使用CEF 嵌入式瀏覽器技術支持使用第三方廠家提供的二代身份證讀卡器SDK 讀取居民身份證信息。通過Web UI 上JS 調用宿主C++代碼操作身份證讀卡器獲取相應信息。通過本實例可充分展示CEF 下JS 與原生C++代碼的相互交互過程。

本實例使用Windows 下Visual Studio2015 版本構架MFC Dialog 應用項目,使用CEF3 3325Chromium 65 版本構建。將展示兩種方式:同步與異步JS 調用原生C++代碼。本示例主要展示CEF 使用中最核心的JS 與C++交互部分,其他部分如宿主應用程序構數據結構、類定義等不再展示,只列出核心代碼。將采用最小化構建。

MFC 工程中初始化CEF,并創建Browser 窗口進程。

(1)App::InitInstance()函數CEF 初始化。

(2)Dlg::OnInitDialog()函數中初始化Browser 窗口進程。

(3)Dlg::OnClose()函數中關閉Browser 進行,并銷毀CEF

(4)使用C++封裝讀卡器SDK 相關函數,創建讀取身份證信息函數ReadIDCardInfo(wstring &info);

5.1 同步版本

JS 端調用C++函數,并在Render 進程處理返回。

(1)派生MyCefApp、MyCefClient 與MyCefV8Handler 類,實現CEF CefApp、CefRenderProcessHandler、CefClient、CefLife SpanHandler、CefV8Handler 等接口。

(2)實現CefRenderProcessHandler::OnContextCreated(),使用CEF Window 綁定,建并綁定JS 函數ReadIDCard 至瀏覽器window對象。

(3)實現CefV8Handler::Execute()。當Web 端JS 代碼中調用ReadIDCard 函數時,CEF 將會觸發Execute()。在Execute()中將調C++原生ReadIDCardInfo 函數獲取居民身份證信息并返回給JS。

詳細步驟如下:

(1)定義MyCefApp 類,實現CefRenderProcessHandler 接口中的OnContextCreated。并在OnContextCreated 函數中定義身份證信息讀取函數ReadIDCard 供Web 端JS 調用。

(2)定義MyCefClient 類,繼承CefClient 與CefLifeSpan Handler。CefClient 提供訪問Browser 實例的回調接口。CefLifeSpan Handler 是與之相關的Browser 實例相關生存周期回調接口,管理Brower 生存周期。

(3)定義MyCefV8Handler 類,繼承CefV8Handler。CefV8 Handler::Execute 提供JS 窗口綁定和擴展的函數回調。實現Execute函數,當Web 端JS 調用ReadIDCard 函數時將回調此函數。

5.2 異步調用

CEF 提供了一個通用的消息路由實現CefMessageRouter,用于在Render 進程中執行的JS 和在Brower 進程中執行的C++之間傳遞異步消息。使用此消息路由即可實現我們所希望的JS 異步調用。

(1)建立全局CefMessageRouterConfig 類實例。并在CEF 初始化時定義CefMessageRouterConfig 中定義在Web 端JS 需調用函數。

CefMessageRouterConfig g_messageRouterConfig;

messageRouterConfig.js_query_function=“cefQuery”;

messageRouterConfig.js_cancel_function=“cefQueryCancel”

(2)在Render 進程處理類MyCefApp 中添加CefMessage RouterRendererSide 成員變量,實現Render 一側消息路由。

m_renderer_side_router=CefMessageRouterRendererSide::Create(g_messageRouterConfig);

(3)在MyCefApp 中分別實現并調用CefMessageRouter RendererSide 預留的OnContextCreated、OnProcessMessageReceived與OnProcessMessageReceived 三個同名接口,使用默認實現即可。

(4)在Browser 進程處理類MyCefClient 中添加CefMessage RouterBrowserSide 成員變量,用于實現Browser 一側消息路由。

m_browser_side_router=CefMessageRouterBrowserSide::Create(g_messageRouterConfig);

(5)在MyCefClient 中分別實現并調用CefMessageRouter BrowserSide 預留 的OnProcessMessageReceived、OnBeforeClose、OnBeforeBrowse 與OnRenderProcessTerminated 四個同名接口,使用默認實現即可。

(6)實現JSHandler 類,繼承自CefMessageRouterBrowserSide::Handler 接口,實現OnQuery 與OnQueryCanceled 函數,用于處理JS 端調用C++而被傳遞過來的消息。

(7)在MyCefClient 類中調用CefMessageRouterBrowserSide成員變量AddHandler 函數,將上述(6)步驟實現的接口實例添加到消息路由中。

JSHandler m_jsHandler;

...

m_browser_side_router->AddHandler(&m_jsHandler,true);

通過上述步驟,當在Web 端調用JS 函數window.cefQuer(‘ReadIDCard’,...)時,Rander 進程將首先捕獲調動,并通過消息路由路由至Browser 進程一側,最終將調用交由CefMessageRouter BrowserSide::Handler 接口實現二代身份證信息的讀取功能,并在完成后異步將數據傳遞給Web 端。

6 總結

通過上述兩例同步與異步應用實例,展示了嵌入式使用CEF時Web 端JS 與宿主端C++的相互調用與數據傳遞過程。通過實例可見CEF為我們隔離了大量的Chromium接口初始化以及實現過程,并提供了豐富的默認實現,第三方應用程序只需定義少量關鍵業務核心代碼即可將CEF 嵌入到第三方應用程序中使用。為我們開發混合應用實例提供了極大的便利。

猜你喜歡
進程定義
永遠不要用“起點”定義自己
海峽姐妹(2020年9期)2021-01-04 01:35:44
定義“風格”
債券市場對外開放的進程與展望
中國外匯(2019年20期)2019-11-25 09:54:58
成功的定義
山東青年(2016年1期)2016-02-28 14:25:25
我國高等教育改革進程與反思
教育與職業(2014年7期)2014-01-21 02:35:04
修辭學的重大定義
當代修辭學(2014年3期)2014-01-21 02:30:44
Linux僵死進程的產生與避免
山的定義
公務員文萃(2013年5期)2013-03-11 16:08:37
男女平等進程中出現的新矛盾和新問題
俄羅斯現代化進程的阻礙
主站蜘蛛池模板: 色九九视频| 四虎精品黑人视频| 五月天婷婷网亚洲综合在线| 欧美一级视频免费| 蜜桃视频一区二区| 青青草国产在线视频| 日韩123欧美字幕| 伊人久久青草青青综合| 亚洲欧洲日韩国产综合在线二区| 亚洲精品午夜天堂网页| 日韩av手机在线| 婷婷色狠狠干| 久久夜色撩人精品国产| 久久久久青草大香线综合精品| 免费国产福利| 久久久久久尹人网香蕉 | 天天爽免费视频| 黄片在线永久| 国产欧美视频综合二区| 色综合婷婷| 亚洲一区波多野结衣二区三区| 国产呦视频免费视频在线观看| 视频二区中文无码| 黄色网站在线观看无码| 国产黄色视频综合| 本亚洲精品网站| 激情综合激情| 欧美视频在线播放观看免费福利资源| 久久免费观看视频| 女人18一级毛片免费观看| 东京热av无码电影一区二区| 亚洲视频欧美不卡| 久久亚洲国产一区二区| 成人欧美在线观看| 四虎成人在线视频| 麻豆国产精品| 尤物特级无码毛片免费| 久久青草精品一区二区三区| AV天堂资源福利在线观看| 狠狠v日韩v欧美v| 成人字幕网视频在线观看| 久久久久中文字幕精品视频| 亚洲国产精品久久久久秋霞影院| 97人人模人人爽人人喊小说| 国产精品成人免费综合| 国产成人精品男人的天堂| 深夜福利视频一区二区| 国产精品永久免费嫩草研究院| 欧美精品一二三区| 久久久久青草大香线综合精品| 国产在线91在线电影| 无码人中文字幕| 亚洲无码视频一区二区三区| 精品国产成人a在线观看| 欧美日韩一区二区三区在线视频| 欧美精品综合视频一区二区| 69视频国产| 国产白丝av| 国禁国产you女视频网站| 日本a∨在线观看| 91色国产在线| 日韩福利在线视频| av无码一区二区三区在线| 无码aaa视频| 无遮挡一级毛片呦女视频| 中文字幕人妻无码系列第三区| 亚洲高清无码精品| 国产另类乱子伦精品免费女| 国产欧美成人不卡视频| 国产亚洲日韩av在线| 免费一级α片在线观看| 无码电影在线观看| 亚洲综合二区| 五月婷婷亚洲综合| 亚洲精品天堂自在久久77| 亚洲男人在线| 日韩无码黄色| 国产91小视频在线观看| 亚洲综合极品香蕉久久网| 久久青草精品一区二区三区| 国产尤物视频在线| 国产一级毛片高清完整视频版|