
1.前言
- 組件化 在Android開(kāi)發(fā)的近幾年來(lái),已經(jīng)由單純編寫(xiě)代碼的概念(工具類(lèi)、第三方組件等等)遷移并應(yīng)用于項(xiàng)目的架構(gòu)上,而在應(yīng)用項(xiàng)目架構(gòu)過(guò)程中又演變出多種不同的實(shí)現(xiàn)方案,隨著現(xiàn)代APP應(yīng)用市場(chǎng)的快速發(fā)展,應(yīng)用開(kāi)發(fā)的時(shí)間、效率、穩(wěn)定性、可擴(kuò)展性、靈活性都要體現(xiàn)出高標(biāo)準(zhǔn)的行業(yè)水平,因此開(kāi)發(fā)者就想出把項(xiàng)目劃分多個(gè)模塊,并且需求滿足協(xié)同與獨(dú)立開(kāi)發(fā),組件化就由此誕生。
- 文章中實(shí)例 linhaojian的Github
2.目錄

目錄.png
3.組件化發(fā)展史
- 項(xiàng)目架構(gòu)發(fā)展過(guò)程中,包含非常多種實(shí)現(xiàn)方式,我將它們劃分了三種 傳統(tǒng)、模塊、組件:
項(xiàng)目架構(gòu)分類(lèi).png
3.1 傳統(tǒng)化項(xiàng)目結(jié)構(gòu)

傳統(tǒng)化結(jié)構(gòu).png
- 傳統(tǒng)化結(jié)構(gòu):通過(guò) 項(xiàng)目?jī)?nèi)業(yè)務(wù)分包 的方式進(jìn)行開(kāi)發(fā),這種方式 維護(hù)、擴(kuò)展都非常困難,并且不方便團(tuán)隊(duì)開(kāi)發(fā),只適應(yīng)小項(xiàng)目。
3.2 模塊化項(xiàng)目結(jié)構(gòu)

模塊化結(jié)構(gòu).png
- 模塊化結(jié)構(gòu):在AndroidStudio 開(kāi)發(fā)工具內(nèi),通過(guò) 創(chuàng)建module 的方式進(jìn)行劃分不同的業(yè)務(wù)功能,然后在主項(xiàng)目與module 或者 module間構(gòu)建關(guān)聯(lián)(這種關(guān)聯(lián)方式耦合性高),當(dāng)module不合理設(shè)置的適合,會(huì)出現(xiàn)module之間類(lèi)庫(kù)的冗余或者重復(fù)使用。
3.3 組件化項(xiàng)目結(jié)構(gòu)

組件化結(jié)構(gòu).png
- 組件化結(jié)構(gòu):組件化就是在模塊化的思想上優(yōu)化演變出來(lái),在模塊化思想上,通過(guò)1.抽出module間公用部分;2.使用路由Router解耦module間的交互;3.gradle集成與獨(dú)立配置;4.代碼與資源的隔離,使得module同時(shí)支持集成開(kāi)發(fā)與獨(dú)立開(kāi)發(fā)。
4.定義
- 將重復(fù)的代碼進(jìn)行封裝,業(yè)務(wù)功能劃分為最小粒子。
5.作用
- 1.復(fù)用代碼;
- 2.降低業(yè)務(wù)功能間的依賴(lài)或者關(guān)聯(lián);
- 3.提供單獨(dú)業(yè)務(wù)運(yùn)行與調(diào)試;
6.特點(diǎn)
- 1.module具備獨(dú)立性,可單獨(dú)運(yùn)行或調(diào)試;
- 2.module間高度解耦,通過(guò)路由交互;
- 3.代碼與資源隔離;
- 4.module劃分盡可能粒子化,便于維護(hù)與復(fù)用;
7.組件化架構(gòu)
- 借助以下的包含實(shí)例的圖,便于更深入了解 組件化 的架構(gòu);
組件化分層.png - 圖中總共分4層 組件集成、業(yè)務(wù)組件、功能組件、運(yùn)行環(huán)境;
- 組件集成:將所有業(yè)務(wù)組件組合到APP的空殼項(xiàng)目中(空殼項(xiàng)目中只包含啟動(dòng)頁(yè),無(wú)任何業(yè)務(wù)邏輯);
- 業(yè)務(wù)組件:將項(xiàng)目按照功能需要?jiǎng)澐至6容^小的module;
- 功能組件:將不同業(yè)務(wù)組件中公用部分封裝為各種類(lèi)庫(kù);
- 運(yùn)行環(huán)境:項(xiàng)目開(kāi)發(fā)中所依賴(lài)的語(yǔ)言庫(kù)或者開(kāi)發(fā)環(huán)境;
- 從圖中可以發(fā)現(xiàn),組件化只存在 垂直關(guān)系,使各業(yè)務(wù)功能更獨(dú)立與清晰,更適合現(xiàn)代團(tuán)隊(duì)開(kāi)發(fā)的要求。
8.組件化實(shí)踐
- 下面簡(jiǎn)單配合例子實(shí)踐組件化開(kāi)發(fā)過(guò)程;
- 項(xiàng)目:類(lèi)似于便利生活的應(yīng)用;
- 功能:登錄、注冊(cè)、酒店、外賣(mài);
-
項(xiàng)目結(jié)構(gòu)如下圖:
例子項(xiàng)目結(jié)構(gòu).png
8.1 base公用
- 1.將module間公用的代碼封裝base的庫(kù)(如:Log庫(kù)、Base庫(kù)、網(wǎng)絡(luò)請(qǐng)求庫(kù)等等);
-
2.在4個(gè)模塊中添加引用;
base引用.png
8.2 module獨(dú)立與集成
- 將4個(gè)配置為可以單獨(dú)運(yùn)行或者集成運(yùn)行的狀態(tài):
- 1.打開(kāi)各種module中 gradle.properties文件,添加如下內(nèi)容:
集成于與獨(dú)立配置1.png - 2.打開(kāi)各種module中 build.gradle文件,添加如下內(nèi)容:
集成于與獨(dú)立配置2.png
集成于與獨(dú)立配置3.png -
3.在module獨(dú)立運(yùn)行時(shí),需要為其添加對(duì)應(yīng)獨(dú)立運(yùn)行的AndroidManifest.xml文件:
集成于與獨(dú)立配置4.png
- 1.打開(kāi)各種module中 gradle.properties文件,添加如下內(nèi)容:
-
注:可以通過(guò)修改isRunAlone的賦值,就能改變module的運(yùn)行狀態(tài),true:可獨(dú)立運(yùn)行,false:集成運(yùn)行。
8.3 多Application初始化
- 因?yàn)閙odule已具備獨(dú)立運(yùn)行開(kāi)發(fā)的特點(diǎn),所以開(kāi)發(fā)過(guò)程中module中就會(huì)按照自己功能內(nèi)需求初始化所需的第三方類(lèi)庫(kù)或者工具庫(kù),因此module中就會(huì)存在各自的Application類(lèi),那么在集成開(kāi)發(fā)過(guò)程中,我們也需要把module內(nèi)的Application進(jìn)行初始化調(diào)用,不然就會(huì)與獨(dú)立開(kāi)發(fā)不兼容的問(wèn)題,可以通過(guò) 反射 解決:
8.3.1 實(shí)現(xiàn)原理
- 在 主application 中,通過(guò) 反射 把其他module的Application初始化。
8.3.2 實(shí)現(xiàn)過(guò)程
* 1.創(chuàng)建一個(gè)抽象BaseApplication,其他module都繼承于它。
public abstract class BaseApplication extends Application{
public abstract void init(Context context);// 1
@Override
public void onCreate() {
super.onCreate();
// 初始化所有module公用的類(lèi)庫(kù)
initPublic();
// 初始化不同module的Application
init(getApplicationContext());// 2
}
/**
* 初始化Module功能的類(lèi)庫(kù)
*/
public void initPublic(){
ARouter.init(this);
}
}
- 注釋1:提供抽象init方法,使其他module都在init函數(shù)中進(jìn)行初始化。
- 注釋2:統(tǒng)一和兼容集成與獨(dú)立的2種開(kāi)發(fā)環(huán)境
- 2.讓Login組件繼承BaseApplication
public class LoginAppcation extends BaseApplication {
@Override
public void init(Context context) {
//初始化 login組件 中使用的類(lèi)庫(kù)
// dagger2 、rxjava ....
}
}
* 3.在主項(xiàng)目或者main組件中,通過(guò)反射進(jìn)行初始化
public class MainAppcation extends BaseApplication {
//module中application類(lèi)的路徑
private static final String[] MODULESLIST =
{"com.lhj.component.login.LoginAppcation"};
@Override
public void init(Context context) {
//初始化 main組件 中所需的類(lèi)庫(kù)
// 初始化其他module的Application
modulesApplicationInit(context);
}
/**
* 通過(guò)反射的方式,獲取指定Application類(lèi)的實(shí)例,并調(diào)用init函數(shù),解決組件化多appplication獨(dú)立的問(wèn)題
*/
private void modulesApplicationInit(Context context){
for (String moduleImpl : MODULESLIST){
try {
Class<?> clazz = Class.forName(moduleImpl);
Object obj = clazz.newInstance();
if (obj instanceof BaseApplication){
((BaseApplication) obj).init(context);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
}
- 通過(guò) 反射 很好的解決組件獨(dú)立開(kāi)發(fā)的多個(gè)Application初始化問(wèn)題,并且同時(shí)兼容集成開(kāi)發(fā)環(huán)境,但是反射就存在性能的問(wèn)題,但暫時(shí)沒(méi)有想到一個(gè)更好的解決方案,請(qǐng)各位大神可以評(píng)論指教。
8.4 module間界面的跳轉(zhuǎn)
- 路由Router的誕生就是為了解決module間界面跳轉(zhuǎn)耦合問(wèn)題,在這里我們可以使用阿里的Arouter,如果對(duì)該框架不熟悉,可以查看我之前的文章Android ARouter:最簡(jiǎn)單&粗暴(使用與原理)講解。
8.5 代碼隔離
- 在集成開(kāi)發(fā)中,主項(xiàng)目需要對(duì)4個(gè)模塊進(jìn)行引用,但為了防止在主項(xiàng)目編譯時(shí)引用了其他module內(nèi)的類(lèi)的問(wèn)題,所以需要實(shí)現(xiàn)代碼隔離,使得真正意義上獨(dú)立。
-
可以在引用module時(shí),使用以下方式:
代碼隔離.png
8.6 資源隔離
- 在集成開(kāi)發(fā)中,如果module之間存在資源名字相同的情況時(shí),可能會(huì)影響項(xiàng)目的運(yùn)行或者誤導(dǎo)開(kāi)發(fā)人員,
所以建議為不同module的資源文件添加對(duì)應(yīng)的命名規(guī)則:- 1.xml內(nèi)(string、colors等資源文件)的命名方式可以通過(guò)如下配置方式;
- 如:將登錄module的xml文件
android {
//...
// 實(shí)現(xiàn)資源隔離
resourcePrefix "login_"
}
* 2. 對(duì)于控件名稱(chēng)與文件名稱(chēng),可根據(jù)自己的喜歡區(qū)分;
8.7 數(shù)據(jù)復(fù)用
- 項(xiàng)目開(kāi)發(fā)過(guò)程中,經(jīng)常會(huì)出現(xiàn)數(shù)據(jù)需要全局應(yīng)用,因此在多module間需要實(shí)現(xiàn)數(shù)據(jù)復(fù)用,可以通過(guò)以下方式實(shí)現(xiàn):
- 1.使用Arouter框架中的Provider功能(將復(fù)用的數(shù)據(jù)保存base庫(kù)的Provider中,然后通過(guò)Arouter的navigation函數(shù)獲?。?/li>
- 2.base庫(kù)中,可以按需添加對(duì)象全局?jǐn)?shù)據(jù)的管理類(lèi)。
8.8 資源復(fù)用
- 將可能會(huì)復(fù)用的資源,添加至base庫(kù)中,防止資源重復(fù)的問(wèn)題。
9.總結(jié)
- 到此,Android項(xiàng)目組件化開(kāi)發(fā)介紹完畢!
- 如果喜歡我的分享,可以點(diǎn)擊 關(guān)注 或者 贊,你們支持是我分享的最大動(dòng)力 。
- linhaojian的Github
歡迎關(guān)注linhaojian_CSDN博客或者linhaojian_簡(jiǎn)書(shū)!
不定期分享關(guān)于安卓開(kāi)發(fā)的干貨。
寫(xiě)技術(shù)文章初心
- 技術(shù)知識(shí)積累
- 技術(shù)知識(shí)鞏固
- 技術(shù)知識(shí)分享
- 技術(shù)知識(shí)交流








