前文在API規劃時就已經有提到過組件API這個概念,本文將會介紹它的原理以及實現前端
quick.ui.xxx quick.page.xxx
在quick hybrid中,API是按模塊劃分的,如ui
,page
等都是不一樣模塊,而模塊的另外一個名稱則是組件
git
爲何叫組件?能夠這樣理解,模塊更多的是H5前端的叫法(由於在前端看來不一樣API分別屬於不一樣的模塊下),
而組件則是原生那邊增強的理解概念(由於,每個組件都是能夠在項目中單獨存在的,譬如項目A中有組件pay
,但項目B卻不必定集成有)github
回到最初,quick hybrid的使命就是服務於N個項目,那麼會遇到一個問題-N個項目中可能會有很是多的須要以API方式提供的需求,可是考慮到體積以及通用性,並非全部的都適合直接集成到框架中api
此時,就須要對框架內容和項目內容進行區分,因而就有了框架API和組件API的概念(此時能夠認爲原生中框架文件是單獨打成一個靜態包給項目引用的,項目沒法直接修改)app
框架API框架
直接打包到框架文件中(前端的quick.native.js
,原生框架包中的API都會包含)ui
使用的時候直接quick.xx模塊.xx功能
便可調用(由於前端會將框架API都默認封裝)3d
config
配置時無需單獨註冊(由於默認狀況會註冊好)code
部分框架API會有H5下的實現(如部分系統級API都是有H5下的實現的)blog
組件API
框架中不會包含,由各自的項目自行開發或集成(如某項目單獨集成一個個性化語音組件)
使用的時候必須用quick.callAPi(...)
並傳入合適參數(由於框架不會集成,須要經過這個萬金油方法調用)
config
配置時必須註冊(須要傳入組件別名註冊,由於框架內部不知道這些新組件的)
全部組件API都只是quick環境下的實現(通常都是一些原生中集成的拓展功能)
項目中默認只會打包框架API,可是框架的功能是有限的(只會集成一些最經常使用的功能),若是遇到一些個性化的需求(如支付,語音等等),則須要項目拓展組件API,整體步驟以下:
1.原生引入框架,並實現對應的API接口,編寫API的功能代碼
2.原生在項目配置文件中(不是框架配置文件)聲明對應的別名和路徑關係
3.H5頁面初始化時,config
,並傳入對應須要註冊的組件的別名
4.容器接收到config方法後,去配置文件中根據別名找路徑,而後註冊對應路徑下的API類
5.註冊成功後,H5頁面中經過callAPi
來調用新註冊的組件API
原生中API的定義以下(以pay組件爲示例)
Android中
public class PayApi implements IBridgeImpl { public static void payCustom(..., JSONObject param, final Callback callback) { // 作對應的支付工做,作完後回調 ... callback.apply(...); } }
iOS中
@implementation PayApi - (void)registerHandlers { [self registerHandlerName:@"payCustom" handler:^(id data, WVJBResponseCallback responseCallback) { // 作對應的支付工做,作完後回調 ... responseCallback(...); }]; }
須要注意的是,Android和iOS中別名請保持一致,通常狀況下鍵值對也可
譬如以示例項目爲例,
Android在app
模塊下的assets/modules.properties
中
pay = com.quick.quickhybrid.api.PayApi ...
同理iOS中也相似,只不過右側的路徑值能夠換爲iOS中的,如
pay = PayApi
能夠看到,Android和iOS中的別名名稱相同,可是路徑不一致(由於各類的包機制不同)
H5中須要在config註冊拓展的組件,須要傳入別名(別名有對應的文檔說明-通常狀況下同類型組件的別名是固定的)
quick.config({ jsApiList: ['pay'] }); // error表明發生錯誤 quick.error(...); // ready中是註冊成功 quick.ready(...);
原生容器接收到config請求後就開始註冊組件,以下
// RegisterName: ui,page,pay之類的組件(模塊)名 // RegisterNclass: 對應的路徑,Android中和iOS中不一致 // RegisterNclass: 如com.quick.quickhybrid.api.PayApi JSBridge.register(RegisterName, RegisterNclass);
// RegisterNclass: 如PayApi [self registerHandlersWithClassName:@"RegisterNclass" moduleName:@"RegisterName"];
註冊成功後,H5中經過特定方法調用
quick.callApi({ name: 'testPay', mudule: 'pay', // 額外參數常常都須要 data: {...}, success: function(result) { quick.ui.toast(JSON.stringify(result)); }, error: function(error) {}, });
實際狀況下,當項目足夠多時,拓展組件API是一種很是常見的場景,所以制定規範是頗有必要的。
另外,通常狀況下,不少相同功能的組件都是能夠一塊兒積累,多個項目複用的(好比支付,特定業務組件等等)
github
上這個框架的實現