前文《天貓客戶(hù)端組件動(dòng)態(tài)化的方案——VirtualView 上手體驗(yàn).md》都提到了自定義模板編譯成二進(jìn)制數(shù)據(jù)的過(guò)程,在 Android 版的 Playground 里內(nèi)置了一個(gè)編譯工具可以實(shí)時(shí)調(diào)測(cè),然而業(yè)務(wù)開(kāi)發(fā)過(guò)程中,不可能在手機(jī)上編譯,而是在電腦或者后臺(tái)去編譯模板。因此這里提供了一個(gè)獨(dú)立的工具來(lái)編譯模板,這里介紹下它的使用方法。
前世今生
工具的源碼也提交在 github 上。在一開(kāi)始的設(shè)計(jì)里,編譯模塊是針對(duì)控件來(lái)設(shè)計(jì)的,每一個(gè)控件如 NText、NImage、VHLayout 等都有自己的編譯類(lèi),編譯類(lèi)的繼承結(jié)構(gòu)體系與控件本身的繼承結(jié)構(gòu)體系一樣。它們各自會(huì)解析對(duì)應(yīng)控件的屬性及控件本身的類(lèi)型,將其轉(zhuǎn)換成整型值或索引序列化到最終輸出文件里;這就帶來(lái)了一個(gè)問(wèn)題,當(dāng)需要擴(kuò)展控件屬性,或者添加自定義控件的時(shí)候,需要編寫(xiě)一個(gè)新的編譯類(lèi)注冊(cè)到編譯工具里,這對(duì)開(kāi)發(fā)者來(lái)說(shuō)十分不友好,且不說(shuō)還得搭建編譯工具工程的本身的運(yùn)行環(huán)境,還得熟悉編譯器類(lèi)的編寫(xiě)邏輯才行。從下圖的原始設(shè)計(jì)圖就可以看出其復(fù)雜性。

為了解決這一弊端,對(duì)原始設(shè)計(jì)進(jìn)行了重構(gòu),重構(gòu)的核心目標(biāo)就是不依賴(lài)源碼就能進(jìn)行模板編譯,思路是通過(guò)配置化的方式聲明描述控件類(lèi)型、屬性類(lèi)型、解析方式等,方案實(shí)施上是將原先針對(duì)控件編寫(xiě)編譯類(lèi)的模式改成針對(duì)屬性來(lái)編譯寫(xiě)編譯類(lèi),只需要一個(gè)通用的屬性編譯類(lèi)即可,具體行為都通過(guò)配置文件來(lái)描述。將重構(gòu)后的工具模板導(dǎo)出可執(zhí)行文件,就可以在項(xiàng)目中直接使用了。廢話(huà)了這么多,接下來(lái)就是本文的重點(diǎn)了。
使用說(shuō)明
獨(dú)立運(yùn)行模式
文件介紹
下載源碼之后,可執(zhí)行工具存放在目錄 TemplateWorkSpace 里,包含以下幾個(gè)文件/目錄(或運(yùn)行后產(chǎn)生):
| 文件 | 作用 |
|---|---|
| config.properties | 配置組件 ID、xml 屬性對(duì)應(yīng)的 value 類(lèi)型 |
| templatelist.properties | 編譯的模板文件列表 |
| build | 二進(jìn)制文件的輸出目錄 |
| template | xml 的存放路徑 |
| compiler.jar | java 代碼編譯后 jar 文件,執(zhí)行 xml 的編譯邏輯 |
| buildTemplate.sh | 編譯執(zhí)行文件 |
如何運(yùn)行
- 打開(kāi)命令行 執(zhí)行
sh buildTemplate.sh - 模板編譯后的文件會(huì)輸出到 build 路徑下
配置 config.properties
-
VIEW_ID_XXXX- 配置 xml 節(jié)點(diǎn) id
- 如配置
VIEW_ID_FrameLayout=1,則 xml 節(jié)點(diǎn)中的<FrameLayout>在編譯后會(huì)用數(shù)值1代替 - 節(jié)點(diǎn)配置以
VIEW_ID_開(kāi)頭
-
property=ValueType- 配置屬性值的類(lèi)型,配置對(duì)所有模板生效,不支持在 1.xml 和 2.xml 中對(duì)相同的屬性用不同的 ValueType 解析
- 目前已經(jīng)支持
- 常規(guī)類(lèi)型:
String(默認(rèn),不需要配置)、Float、Color、Expr、Number、Int、Bool - 特殊類(lèi)型
Flag、Type、Align、LayoutWidthHeight、TextStyle、DataMode、Visibility - 枚舉類(lèi)型
Enum<name:value,……>- 枚舉說(shuō)明:
- 如配置
flexDirection=Enum<row:0,row-reverse:1,column:2,column-reverse:3> - 在解析屬性是配置
row直接轉(zhuǎn)化成int:0,row-reverse轉(zhuǎn)成int:1
- 如配置
- 枚舉說(shuō)明:
- 常規(guī)類(lèi)型:
-
DEFAULT_PROPERTY_XXXX- 為了兼容就模板的編譯,寫(xiě)的強(qiáng)制在二進(jìn)制中寫(xiě)入一些屬性類(lèi)型定義,可以忽略
配置 templatelist.properties
- 格式
xmlFileName=outFileName,Version[,platform]-
xmlFileName標(biāo)識(shí) template 目錄下需要編譯的 xml 文件名建議不帶.xml后綴,目前做了兼容 -
outFileName輸出到 build 目錄下的.out文件名 -
Version表示 xml 編譯后的版本號(hào) -
platform同時(shí)兼容 iOS 和 android 時(shí)不寫(xiě),可填的值為android和iphone
-
xml 文件模板編寫(xiě)
- 和以前的方式一樣,不需要額外寫(xiě) Java 代碼,只需要對(duì)新增的屬性在config.properties 中配置 ValueType
接口模式
除了直接使用命令行執(zhí)行工具,還可以基于此搭建完整成熟的模板工具,它可以是個(gè)客戶(hù)端,也可以是個(gè)后端服務(wù),或者是個(gè)插件,所以需要提供接口模式供宿主程序調(diào)用。
//初始化構(gòu)建對(duì)象
ViewCompilerApi viewCompiler = new ViewCompilerApi();
//設(shè)置配置文件加載器
viewCompiler.setConfigLoader(new LocalConfigLoader());
//讀取模板數(shù)據(jù)
FileInputStream fis = new FileInputStream(rootDir);
//調(diào)用接口,傳入必備參數(shù),此時(shí)不區(qū)分平臺(tái),如果要區(qū)分平臺(tái),使用方單獨(dú)編譯即可
byte[] result = viewCompiler.compile(fis, "icon", 13);
預(yù)覽 VirtualView
有了編譯工具還不夠,我們還需要更加方便的開(kāi)發(fā)體驗(yàn),比如實(shí)時(shí)預(yù)覽。在貓客內(nèi),我們配合模板平臺(tái),集成了掃碼預(yù)覽的能力。對(duì)于開(kāi)發(fā)階段,我們還需要從模板編譯到預(yù)覽的一條龍服務(wù),因此封裝了這么一個(gè)小工具。
工具提交在 github
簡(jiǎn)介
本腳本基于 buildTemplate.sh 腳本,整合了『編譯』-『上傳』-『刷新』的流程。目的在于讓模板編寫(xiě)之后自動(dòng)刷新預(yù)覽。
依賴(lài)環(huán)境
- python
- adb
- Java
使用方法
python buildAndPreview.py VH2Layout
參數(shù)是模板名稱(chēng),也就是當(dāng)前要修改、預(yù)覽的模板,與 templatelist.properties 里的名稱(chēng)一致。
previewconfig.conf 配置參數(shù)
- 推送編譯后的 .out 文件到手機(jī)存儲(chǔ)的路徑
[path]
target = /sdcard/com.tmall.wireless.virtualviewdemo/virtualview/
- 預(yù)覽app的預(yù)覽界面
[preview]
activity = com.tmall.wireless.virtualviewdemo.debug/com.tmall.wireless.virtualviewdemo.PreviewActivity
以上默認(rèn)值都是基于 VirtualView-Android 的 demo 里配置的,可以自行遷移 demo 代碼到自己的 app 環(huán)境中進(jìn)行預(yù)覽。
默認(rèn)配置文件:
預(yù)覽客戶(hù)端
默認(rèn)基于 VirtualView-Android 的 demo,當(dāng)有自定義控件的時(shí)候,需要修改預(yù)覽 app 里,添加自定義組件注冊(cè)邏輯,因此建議參考 demo 配置自己的預(yù)覽環(huán)境。(注意確保手機(jī)有讀SD卡權(quán)限)