1、什么是組件化
個人認(rèn)為組件化是模塊化的一個升華,將功能、業(yè)務(wù)劃分之后每個模塊在開發(fā)過程中還可以單獨運(yùn)行,各個模塊之間隔離,解耦,便于后期升級維護(hù)具體可以參考這系列文章,作者通過編寫gradle的方式實現(xiàn),已經(jīng)將其方案做成開源庫了。我這里只是通過實踐來加深理解組建化和自定義注解的使用。主要注意的點就是:進(jìn)行模塊的劃分,開發(fā)時的模塊單獨運(yùn)行,模塊之間的通信
2、開始(利用wanAndroid的api做一個app)
? ? 1、劃分模塊(不能單獨運(yùn)行的以component開頭,可以單獨運(yùn)行的以module開頭)
? ? ? ? 跟邏輯無關(guān),只提供功能的模塊:
? ? ? ? component_banner:輪播圖
? ? ? ? component_adapter:recyclerView的適配器
? ??????component_network:網(wǎng)絡(luò)請求相關(guān)
????????根據(jù)業(yè)務(wù)邏輯拆分可以單獨運(yùn)行的模塊
? ??????module_account:賬號模塊
? ? ? ? module_article:文章模塊
? ? ? ? module_project:工程模塊
? ? ? ? module_search:搜索模塊
? ? ? ? 公共模塊
? ? ? ? component_res:公共資源模塊
? ? ? ? component_sdk:sdk依賴
? ? ? ? component_widget:通用自定義View相關(guān)
? ? ? ? component_widget:公用模塊
? ? 2、處理開發(fā)期和發(fā)布期
? ? ? ? 因為開發(fā)期間業(yè)務(wù)模塊可以單獨運(yùn)行,所以對于gradle需要單獨處理,通過一個變量canRunAlone控制
? ? ? ? 在開發(fā)期間將模塊設(shè)置為application,在發(fā)布時將其設(shè)置為library
? ? ? ? 開發(fā)期間模塊需要有入口activity,開發(fā)期間有入口activity和相應(yīng)的manifest
? ? 3、如何實現(xiàn)模塊隔離
? ? ? ? ? ?因為所有的模塊最后都要提供給app調(diào)用,模塊之間也會存在相互調(diào)用的情況,所以只是像上面那樣劃分模塊之后模塊之間并不能通信。我 ????這里采用注解的方式,在編譯期間生成代碼將各個模塊整合起來。可以在在公共模塊編寫接口,每個模塊通過這個接口對外暴露功能,面向接? ? ? 口編程。注解的思路:在公共模塊聲明被需要被暴露的接口,各個模塊實現(xiàn)注解,在app初始化注解。
使用@XmoduleInject來聲明要暴露的module接口,在編譯以后會生成ModuleManager類可以獲取到所有的接口實現(xiàn)各個模塊之間的相互調(diào)用,
由于生成的代碼位于common模塊中,所以所有的模塊都可調(diào)用到這個類。生成根據(jù)上面的配置ModuleManager會是這樣的:
public class ModuleManager {
private static ModuleManager instance;
? ? private AccountModule mXModuleAccount;
? ? private ArticleModule mXModuleArticle;
? ? private ProjectModule mXModuleProject;
? ? private SearchModule mXModuleSearch;
? ? private AppModule mXModuleApp;
? ? private ModuleManager() {
}
public static ModuleManager getInstance() {
if (instance ==null) {
Class var0 = ModuleManager.class;
? ? ? ? ? ? synchronized(ModuleManager.class) {
if (instance ==null) {
instance =new ModuleManager();
? ? ? ? ? ? ? ? }
}
}
return instance;
? ? }
public AccountModule getXModuleAccount() {
return this.mXModuleAccount;
? ? }
public void setXModuleAccount(AccountModule param) {
this.mXModuleAccount = param;
? ? }
public ArticleModule getXModuleArticle() {
return this.mXModuleArticle;
? ? }
public void setXModuleArticle(ArticleModule param) {
this.mXModuleArticle = param;
? ? }
public ProjectModule getXModuleProject() {
return this.mXModuleProject;
? ? }
public void setXModuleProject(ProjectModule param) {
this.mXModuleProject = param;
? ? }
public SearchModule getXModuleSearch() {
return this.mXModuleSearch;
? ? }
public void setXModuleSearch(SearchModule param) {
this.mXModuleSearch = param;
? ? }
public AppModule getXModuleApp() {
return this.mXModuleApp;
? ? }
public void setXModuleApp(AppModule param) {
this.mXModuleApp = param;
? ? }
}
使用@Xmodule來聲明被暴露的接口的具體實現(xiàn),注意XModule中填寫的字符串需要跟common模塊中的聲明列表里面一一對應(yīng)
使用XModuleInject來生成初始化類,調(diào)用初始化類的init方法初始化代碼。生成的類名根據(jù)填入的value值確定,如上圖填入的是ModuleInject那么生成的類名就是ModuleInject,如果填入ModuleTest那么生成的就是ModuleTest
4、如何調(diào)用
如上圖,app殼工程中只有一個MainActivity,里面的三個fragment都是來自于其他的三個模塊,我們通過ModuleManager拿到各個模塊對外暴露的接口,然后用這個接口來調(diào)用
如上圖在登錄成功后要返回到首頁,這里也是通過ModuleManager拿到App模塊暴露的接口進(jìn)行
完整demo:https://github.com/yaozhukuang/component,整個工程使用組件化方案構(gòu)建,每個模塊都是使用MVP的模式編寫包含了對某些常用功能模塊的抽取如:輪播圖、網(wǎng)絡(luò)、adapter等等。由于代碼使用kotlin編寫所以跟java稍有不同