網(wǎng)易 Duilib:功能全面的開(kāi)源桌面 UI 開(kāi)發(fā)框架
Duilib 是 Windows 系統下的開(kāi)源的 DirectUI 界面庫(遵循 BSD 協(xié)議),完全免費,可用于商業(yè)軟件開(kāi)發(fā)。
Duilib 可以簡(jiǎn)單方便地實(shí)現大多數界面需求,包括換膚、換色、透明等功能,支持多種圖片格式,使用 XML 可以方便地定制窗口,能較好地做到 UI 和邏輯相分離,盡量減少在代碼里創(chuàng )建 UI 控件。目前,Duilib 已經(jīng)在國內有較為廣泛的使用。
網(wǎng)易在研發(fā)網(wǎng)易易信 PC 版時(shí)引入 Duilib,經(jīng)過(guò)多年開(kāi)發(fā)和改進(jìn),由網(wǎng)易云信在2019年4月開(kāi)源。(github 地址:https://github.com/netease-im...)
網(wǎng)易 Duilib 使用 C++11 重寫(xiě),在其原有基礎上做了較大重構,搭配谷歌的基礎組件 Base 庫、基于 Chromium 的 WebView 框架 CEF 以及常用的 UI 組件,形成了一套功能強大、簡(jiǎn)單易用的完整桌面 UI 開(kāi)發(fā)框架。
02 網(wǎng)易 Duilib 整體框架2.1 整體組件架構框架中提供了多線(xiàn)程模型、高精度定時(shí)器、基本的 xml 解析、zip 解壓等功能;封裝了一層渲染接口和全局樣式資源的統一管理;并且對 DPI 適配、多語(yǔ)言、虛擬鍵盤(pán)、手寫(xiě)板等功能增加了支持;在上層提供了豐富的控件。
2.2 線(xiàn)程模型和消息隊列
開(kāi)發(fā)框架中集成了 Chromium 中 base 庫的線(xiàn)程模型和消息隊列,base 中包含了多種消息循環(huán)、異步操作接口。

base 線(xiàn)程消息循環(huán)
網(wǎng)易 Duilib 框架中的 UI 消息循環(huán)、工作線(xiàn)程都完全依托 base 的線(xiàn)程模型。使用 base 的異步通信能力,我們可以將耗時(shí)的工作(如資源解析)放到輔助線(xiàn)程來(lái)減輕 UI 線(xiàn)程的壓力。

base異步通信
同時(shí),網(wǎng)易 Duilib 中的各種基礎組件,都已經(jīng)繼承了 base 中的生命周期檢測能力,每個(gè)任務(wù)在執行時(shí)都會(huì )先檢查與之綁定的對象是否存活,確保多線(xiàn)程操作不會(huì )因野指針而導致崩潰。實(shí)際項目開(kāi)發(fā)中,使用base的線(xiàn)程模型,我們可以非常簡(jiǎn)單做到 UI 線(xiàn)程、數據庫線(xiàn)程、網(wǎng)絡(luò )線(xiàn)程、其他工作線(xiàn)程之間的通信與交互,有效提升開(kāi)發(fā)速度。
網(wǎng)易 Duilib 框架提供了更加完整和豐富的功能,以滿(mǎn)足不同真實(shí)業(yè)務(wù)場(chǎng)景的需求:
豐富的控件、簡(jiǎn)易的布局
靈活的控件組合、事件處理方式
模塊化支持
優(yōu)化渲染效率
異形窗體支持
DPI 適配支持
多國語(yǔ)言支持
通用樣式支持
虛表控件支持
虛擬鍵盤(pán)支持
實(shí)用的多線(xiàn)程支持
CEF webview 支持
控件動(dòng)畫(huà)、GIF 動(dòng)畫(huà)支持
觸控設備支持(Surface、Wacom)
抽象渲染接口(為其他渲染引擎提供支持)
網(wǎng)易 Duilib 中,增加了控件與容器的尺寸自適應功能,免去繁瑣的手寫(xiě)尺寸。同時(shí)增強了布局能力,搭配控件的一些定位屬性,可以使用少量 xml 代碼來(lái)完成更加強大的布局效果。

新增的絕對布局
現在的 UI 庫中,把布局、容器、控件等邏輯組件拆分開(kāi),讓不同的布局可以與任意容器進(jìn)行靈活的組件。并且弱化了容器與控件的區別,基礎控件使用模版來(lái)編寫(xiě),上層使用時(shí)可以讓它繼承不同的控件或模版,讓控件本身也可以是容器:
typedef LabelTemplate<Control> Label; typedef LabelTemplate<Box> LabelBox; typedef ButtonTemplate<Control> Button; typedef ButtonTemplate<Box> ButtonBox; typedef CheckBoxTemplate<Control> CheckBox; typedef CheckBoxTemplate<Box> CheckBoxBox;
基礎控件繼承了容器后,就可以擁有控件本身的行為+容器的組合能力。這樣做的優(yōu)點(diǎn)是如果一個(gè)基礎組件在 UI 上無(wú)法滿(mǎn)足需求,那么就讓他成為容器去任意組合其他的 UI 組件,提升控件的表現能力。同時(shí)控件支持在 xml 中編寫(xiě)簡(jiǎn)單的事件處理邏輯,把一些功能簡(jiǎn)單的UI控制邏輯放在 xml 中。
3.3 功能強大的 web 展現組件:CEF WebViewCEF(Chromium Embedded Framework)是基于谷歌 Chromium 瀏覽器內核封裝出的跨平臺 web browser 組件。
CEF 內部有完整的一套消息循環(huán),我們將網(wǎng)易 Duilib 框架中的 base 線(xiàn)程模型與 CEF 消息循環(huán)組合在一起。同時(shí)封裝CEF的離屏渲染模式(OSR)、窗口模式為網(wǎng)易 Duilib 中的控件 CefControl、CefNativeControl,讓 CEF 的 WebView 能力完整的嵌入到網(wǎng)易 Duilib 中。最后我們封裝了js與native的通信能力 JsBridge。

CEF執行流程
如此,我們可以使用 CefControl、CefNativeControl 來(lái)做單純的 web 展示控件,也可以以 WebView 為核心,網(wǎng)易 Duilib 為輔助,開(kāi)發(fā) web app。UI 層的展現都由 web 頁(yè)面負責,底層的核心邏輯、數據庫、網(wǎng)絡(luò )等由 C++ 負責,web 與 C++ 使用 JsBridge 通信。
04 應用實(shí)例:有道精品課有道精品課是網(wǎng)易旗下在線(xiàn)教育平臺,教師通過(guò)在線(xiàn)直播的方式對學(xué)生授課,需要一個(gè)支持直播、聊天、課件分享、手寫(xiě)板、web、答題互動(dòng)等功能的客戶(hù)端讓老師使用,因此有道精品課教師端應運而生。
老師可以使用有道精品課教師端進(jìn)行 PPT、PDF、桌面共享、iPad 投屏、視頻播放等多種直播方式 。老師也可以把講課過(guò)程中畫(huà)板上的板書(shū)和課件導出為 PDF 分享給學(xué)生。

有道精品課教師端
我們需要讓教師端滿(mǎn)足各種直播需求的同時(shí),保證開(kāi)發(fā)的速度、易用性、擴展性。另外,由于音視頻、聊天等功能需要消耗大量 CPU 資源,這就要求客戶(hù)端的 UI 本身只能占用較低的內存和 CPU 資源?;谝陨闲枨?,我們使用網(wǎng)易 Duilib 框架進(jìn)行了有道精品課教師端的開(kāi)發(fā)。
教師端的畫(huà)板擁有豐富的功能:繪制各種圖形圖片、圖形交互、書(shū)寫(xiě)文本、PPT解析、動(dòng)畫(huà)、導出 PDF、縮放等等。
畫(huà)板支持的特性越復雜,就越需要消耗更多的 CPU。為了節省 CPU 資源,我們搭配網(wǎng)易 Duilib 框架中的渲染引擎,設計了6層緩存機制,讓畫(huà)板在支持豐富功能的同時(shí)保證極低的 CPU 占用率。

畫(huà)板的多層緩存方案
依托于網(wǎng)易 Duilib 框架的 UI 組件和渲染能力,教師端畫(huà)板可以支持手寫(xiě)板筆跡、毛筆,支持繪制各種圖形圖片,支持畫(huà)板縮放。

毛筆

圖形圖畫(huà)

圖形圖畫(huà)
由于老師的課件大多為 PPT 編寫(xiě),為了讓老師授課更加方便,教師端支持導入 PPT。并且使用網(wǎng)易 Duilib 框架的動(dòng)畫(huà)能力,來(lái)支持展現 PPT 元素的動(dòng)畫(huà),讓老師方便播放動(dòng)畫(huà)或控制 PPT 元素。

支持PPT動(dòng)畫(huà)
配合網(wǎng)易 Duilib 框架的 WebView 能力,可以把 web 頁(yè)面融入到畫(huà)板里,既可以操作網(wǎng)頁(yè)也可以寫(xiě)書(shū)板書(shū),極大增強畫(huà)板表現力。使用這樣的能力,我們可以讓教師端支持展現數學(xué)互動(dòng)題、物理實(shí)驗、化學(xué)實(shí)驗等等內容。

畫(huà)板內嵌web
不斷優(yōu)化迭代,與開(kāi)發(fā)者同行目前,我們已經(jīng)將網(wǎng)易 Duilib 開(kāi)源。
github 地址:
https://github.com/netease-im...
歡迎大家使用并與網(wǎng)易 Duilib 同行。
計劃在不久之后,我們將支持矢量圖來(lái)增強 DPI 適配能力,增加更加豐富的動(dòng)畫(huà)(幀動(dòng)畫(huà)、屬性動(dòng)畫(huà)、路徑動(dòng)畫(huà)、特效動(dòng)畫(huà))來(lái)提升 UI 庫的表現力,并替換性能更好的 skia 渲染引擎。
未來(lái),我們將持續迭代優(yōu)化網(wǎng)易 Duilib 框架,不斷的擴展它的功能。在 github 社區里,已經(jīng)有很多的開(kāi)發(fā)者參與到項目的迭代中。
歡迎更多開(kāi)發(fā)者朋友的加入。
特別鳴謝:感謝自網(wǎng)易 Duilib 成立以來(lái),為之貢獻過(guò)以及仍在貢獻代碼的小伙伴們,包括但不限于 陽(yáng)光、redrain、harrison 等。
撰文/ Redrain
編輯/ Ryan
來(lái)源/ 有道技術(shù)團隊(ID: youdaotech)
*博客內容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權請聯(lián)系工作人員刪除。