輕量組件化方案

清量組件化方案一代目

參考得到的方案疹鳄,做了部分修改
項目地址

一. 組件化我們要實現什么:

1.各模塊可以單獨運行


image.png

2.任意模塊聯合調試:


聯合調試

3.代碼隔離猫妙,看上圖雏亚,不管單獨運行還是聯合調試盛卡,每個模塊只引用一個一個項目:ycbaselib系任,,依賴通過配置文件來管理步氏,在整個開發(fā)周期中都不用compile其他module响禽,所以各個模塊之間看不到其他模塊的代碼,各個模塊交互通過路由協(xié)議ycbaselib中的module服務管理荚醒。

二.怎么用

問:怎么單獨運行模塊

答:采用此框架后芋类,如下圖所示每個模塊可以單獨運行


image.png
問:如何掛載其他模塊運行

答:掛載其他module只需要在當前module根目錄的gradle.properties里加下配置debugComponent=ycpublishlib,yccarlib,而不需要在build.gradle中手動添加,在編譯時會根據配置幫你添加依賴界阁,這樣就做到了各個模塊的代碼隔離梗肝。

問:每個模塊需要在Application里做初始化等一些操作,如何做到铺董?

答:在ycbaselib里定義了一個接口IApplicationLike,定義了一些類似Application的方法,該接口定義如下:

public interface IApplicationLike {
   void onCreate(Application application);  //初始化
   void exitApp();          //退出app
   void onTrimMemory(int level);    //內存等級
}

每個模塊可以寫一個實現了該接口的類精续,在對應的方法下做相應的操作坝锰。在編譯期會使用AOP的方式,在真正的Application類里插入這些代碼的調用重付。

問:依賴其他module有幾種方式

答:有兩種依賴方式顷级,compile project或者compile aar,根據配置确垫,假如為:debugComponent=ycpublishlib則會以compile project的方式添加ycpublishlib依賴弓颈,如果是debugComponent=aar:ycpublishlib則會以compile aar的方式添加ycpublishlib依賴,當然前提是你依賴的模塊要發(fā)布過aar文件删掀。

三.ycbaselib放什么

  1. 公共的第三方庫翔冀,注意:是所有模塊都要用到的,比如:網絡框架披泪、數據庫纤子、圖片加載、Rxjava款票,所有業(yè)務相關的第三方庫都放各自模塊控硼。
  2. 公共res資源:圖片、顏色等
  3. 服務管理艾少,各個模塊需要對外提供的服務會放此處:
    image.png

此處只定義各個服務接口卡乾,具體的服務實現放在各個業(yè)務的模塊下。

ServiceHost為服務管理商缚够,有兩個方法:獲取服務和注冊服務幔妨。

//獲取服務
public static<T>  T getService(Class<T> clazz);
//注冊服務
public static<T>  void addService(Class<T> clazz, T instance)潮瓶;  

比如我想獲取用戶模塊的某些東西我先從ServiceHost獲取用戶模塊的服務類:

IUserService service = ServiceHost.getService(IUserService.class);
service.getUserName();

拿到用戶服務類陶冷,就可以使用用戶模塊提供的的功能了,注意:假如當前模塊沒有掛載用戶模塊毯辅, 此處獲取到的用戶服務為空埂伦,要做好判空處理

備注:ycbaselib應該輕量,不含具體業(yè)務思恐,只放所有模塊都要用到的東西沾谜。

四.原理

假設:運行A模塊,A模塊掛載了B模塊和C模塊

  1. 根據編譯命令胀莹,如ycpublishlib:assembleRelease找到當前運行模塊也就是A模塊基跑,將A模塊設為apply:application 其他掛載模塊B、C設為apply:library
  2. 設置SourceSet描焰,每個模塊單獨運行時和作為library時可能代碼和res資源略有不同媳否,此處根據運行模塊(A)和掛載模塊(B栅螟、C)對SourceSet做不同配置
  3. 根據A模塊里的配置文件(放在gradle.properties里),在編譯時添加B篱竭、C模塊依賴 力图,類似于動態(tài)在buildgradle里添加compile project(':Bproject')。掺逼。吃媒。
  4. 編譯結束后,遍歷所有的class文件吕喘,開始字節(jié)碼插入功能赘那,根據A模塊配置文件里的Application類名全稱,找到A模塊的Application類氯质,然后根據根項目配置里的applikename類名的全稱募舟,找到所有實現了IApplicationLike接口的類,然后在Application里挨個調用IApplicationLike對象的相關方法實現其他掛載模塊的初始化工做等病梢。

五.怎么做

配置:

1.在項目根目錄的gradle.properties里添加如下配置:

mainmodulename=app    //主項目是哪個module
applikename = com.yiche.ycbaselib.component.IApplicationLike    //IApplicationLike接口全名

2.在每個模塊下添加gradle.properties文件胃珍,然后添加如下配置:

isRunAlone=true
applicationName = 'com.yiche.circles.CirclesApplication'  //該模塊單獨運行時配置的Application全名
debugComponent=ycpublishlib    //debug依賴
compileComponent=ycpublishlib  //release依賴

3.在項目根目錄build.gradle里:

buildscript {
    repositories {
        //...略...
         jcenter()
    }
    dependencies {
        clclasspath 'com.yiche.litecomponent:ycbuild-gradle:1.0.3'
         //...略...
    }
}

allprojects {
    repositories {
        flatDir {
            dirs '../release_aars' //本地依賴aar時指定目錄
        }
    }
    //...略...
}

4.在每個模塊的build.gradle里:

apply plugin: 'com.yiche.litecomponent'//注意這里,不再是android.application或者library之類
//...略...

5.代碼部分蜓陌,在除主模塊以外其他每個模塊main目錄下新建runalone目錄
這個是單獨運行時使用的,可以只放置一個AndroidManifest.xml觅彰,用來配置application信息以及啟動的Activity等信息,也可以放java目錄和res目錄用于存放代碼和資源文件钮热,運行時會將runalone里的代碼和res和main目錄下的合并填抬。目錄結構如下圖所示。

添加runalone目錄

[參考]以下是插件里的部分源碼隧期,展示合并SourceSet飒责,PS:AndroidManifest不能合并,單獨運行和作為library時各自用各自的


參考參考

f每個模塊寫一個類仆潮,實現ycbaselib模塊下的IApplicationLike接口宏蛉,用于模仿Application該接口定義如下:

public interface IApplicationLike {
    void onCreate(Application application);
    void exitApp();
    void onTrimMemory(int level);
}

類似于Application的功能,在這里根據需求添加模塊的初始化性置、或者退出app時的操作等拾并。這里的代碼會在編譯時動態(tài)插入。
(完畢)

配置說明:

1.根目錄的gradle.properties

mainmodulename:標記哪個模塊是主項目鹏浅,一般都是app嗅义,設置這個是為了當直接輸入assembleRelease等構建命令的時候知道哪個是主項目入口。

ps:編譯某個moudle的命令是gradlew modulename:assembleRelease這樣隐砸。咱們一般敲assembleRelease相當于app:assembleRelease

applikename :IApplicationLike是一個接口之碗,模仿Application的功能,一般放在base包下(比如本項目的ycbaselib包下)季希。為什么要放這個全名呢褪那,因為在編譯時要動態(tài)添加代碼幽纷,會根據這個全名找到所有實現了該接口的類,然后在Application里動態(tài)插入代碼博敬。

問:如何實現模擬Application功能霹崎?
答:當編譯完成后,本框架會通過字節(jié)碼插入的方式冶忱,遍歷所有的class文件找到所有實現了IApplicationLike接口的對象,然后在真正的Application下挨個插入調用代碼境析。

2.模塊目錄的gradle.properties

isRunAlone:一般為true囚枪,只有當本模塊需要發(fā)布library包也就是打aar包的的時候改為false。

applicationName :本模塊單獨運行時指定的Application類全名劳淆。每個模塊都必須定義一個Application链沼,因為每個模塊都可能掛載其他模塊聯合運行,其他模塊有可能需要在Application里做一些操作沛鸵。所以就算本模塊不需要使用Application也需要定義一個Application類括勺。

問:為什么需要在配置里加applicationName呢?
答:在編譯期間需要動態(tài)添加代碼曲掰,根據applicationName找到真正的Application類疾捍,然后再找到所有實現了IApplicationLike接口的類,然后在Application類的對應方法里添加所有IApplicationLike實現類的調用代碼栏妖。

PS:applicationName是強制需要指定的乱豆。你定義的Application可以不寫任何代碼如下圖,這樣也不影響注入代碼的:

//記得在runalone目錄下的AndroidManifest里注冊
public class CarApplication extends Application{
  //我是空的
}

debugComponent吊趾、compileComponent:本模塊debug依賴以及realease依賴宛裕。用于配置聯合其他模塊調試時的依賴,會在編譯期間根據這個配置幫你引用其他項目论泛。

依賴有兩種方式揩尸,比如debugComponent:ycuserlib,aar:yccarlib表示依賴ycuserlib和yccarlib兩個模塊,前者是直接直接compile ycuserlib的projrct屁奏,后者是compile yccarlib發(fā)布的aar文件岩榆。當某個模塊配置isRunAlone為false會打一個aar包并拷貝到根目錄里的release_aars文件夾,當使用aar:ycxxlib依賴時了袁,會到這個目錄下找對應的aar文件并添加依賴朗恳。

其他:

ycuserblib提供了一個無侵入初始化的方案,通過ContentProvider來實現载绿,原理參考使用ContentProvider初始化你的Library粥诫,可以不用在Application的onCreate里加代碼來時現模塊的初始化。

主module的不同之處:

  1. 主module的isRunalone永遠為true崭庸,主module不會作為library使用
  2. 其他模塊不能依賴主module怀浆。
  3. 主module不需要設置runalone目錄谊囚,它不會作為library使用,一直是application模式
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末执赡,一起剝皮案震驚了整個濱河市镰踏,隨后出現的幾起案子,更是在濱河造成了極大的恐慌沙合,老刑警劉巖奠伪,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異首懈,居然都是意外死亡绊率,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門究履,熙熙樓的掌柜王于貴愁眉苦臉地迎上來滤否,“玉大人,你說我怎么就攤上這事最仑∶臧常” “怎么了?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵泥彤,是天一觀的道長欲芹。 經常有香客問我,道長全景,這世上最難降的妖魔是什么耀石? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮爸黄,結果婚禮上滞伟,老公的妹妹穿的比我還像新娘。我一直安慰自己炕贵,他們只是感情好梆奈,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著称开,像睡著了一般亩钟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鳖轰,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天清酥,我揣著相機與錄音,去河邊找鬼蕴侣。 笑死焰轻,一個胖子當著我的面吹牛,可吹牛的內容都是我干的昆雀。 我是一名探鬼主播辱志,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼蝠筑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了揩懒?” 一聲冷哼從身側響起什乙,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎已球,沒想到半個月后臣镣,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡智亮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年退疫,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鸽素。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖亦鳞,靈堂內的尸體忽然破棺而出馍忽,到底是詐尸還是另有隱情,我是刑警寧澤燕差,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布遭笋,位于F島的核電站,受9級特大地震影響徒探,放射性物質發(fā)生泄漏瓦呼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一测暗、第九天 我趴在偏房一處隱蔽的房頂上張望央串。 院中可真熱鬧,春花似錦碗啄、人聲如沸质和。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽饲宿。三九已至,卻和暖如春胆描,著一層夾襖步出監(jiān)牢的瞬間瘫想,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工昌讲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留国夜,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓剧蚣,卻偏偏與公主長得像支竹,于是被迫代替她去往敵國和親旋廷。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355