Android組件化開發(fā)基本應(yīng)用

初始模型


組件化目錄結(jié)構(gòu):



這里需要注意一下,main組件的gradle文件中,apply plugin使用的是com.android.application


其他業(yè)務(wù)模塊,使用的是com.android.library



因為在最終的發(fā)布版中,其他業(yè)務(wù)組件是集成到main組件中的,main組件編譯生成最終的application,或者可以這么理解,main組件和app外殼是我們app的必備組成部分,一起構(gòu)成了可對外發(fā)布的完整app,其他組件可以以集成進來,也可以不集成進來,只會增加或者減少我們app的功能,但不影響我們app的最終發(fā)布。所以我們在新增module的時候,選擇的類型應(yīng)該是library。


各個組件都建立完成之后,接下來可以把組件集成到main組件中,集成非常簡單,只需在main組件的gradle文件中,添加如下語句


各組件單獨開發(fā)

??前面我們把各個組件集成到到main組件,現(xiàn)在我們把組件拆出來,單獨開發(fā),開發(fā)完后,可以再把組件集成到main中,發(fā)布。這是組件化開發(fā)的最大亮點(優(yōu)點)。

??這里我們把home組件單獨出來開發(fā)。第一步,需要把其library模式改為application模式,因為只有application才可以單獨運行,library必須依靠application才能運行。所以,接下來,我們就要在home所對應(yīng)的gradle文件中做修改。


修改成


等要集成到main組件時,又得改回來,如果這樣子手工去改,組件一多,修改起來麻煩,也不優(yōu)雅。優(yōu)雅的解決辦法就是,設(shè)置一個開關(guān),打開時,就是application模式,可以單獨開發(fā),關(guān)閉時,就是library模式,可以集成到main組件中。

??在項目根目錄下,有一個gradle.properties文件


在這文件中,我們可以添加一個常量isDebug,值設(shè)為true。


這里設(shè)置了常量之后,我們項目中的其他build.gradle文件都可以把這個常量讀取出來,所以我們可以在home的build.gradle文件中,讀取該常量的值,動態(tài)設(shè)置applyplugin。


這樣子設(shè)置之后,當(dāng)我們需要切換模式時,只需要修改gradle.properties文件中isDebug的值,修改完成之后,點擊Project sync按鈕同步一下,如果有報錯,那么還有個地方需要修改一下,就是main組件的build.gradle文件,看下圖


為什么做這樣的修改?因為我們把module的模式改成了application了,這里不能引入application,引入的話會報錯,所以當(dāng)是debug模式時(也就是組件單獨開發(fā)時),這里就不引入該組件,免得報錯。

??接下來,還得修改?AndroidManifest.xml。因為當(dāng)我們把一個module設(shè)置為application時,其AndroidManifest.xml需要包含一個app所需要的屬性,例如app的icon、theme、launch Activity這些屬性設(shè)置,而當(dāng)module為library時,上面所提的這些屬性都不需要用到,所以當(dāng)我們處于不同模式時,AndroidManifest.xml文件也得不同。我們在home的src文件夾中新創(chuàng)建一個目錄為debug目錄,再把我們用于debug時的AndroidManifest.xml文件放進去。由于在Android目錄模式下比較難創(chuàng)建這個目錄,所以我們可以選另外一種目錄模式(Project目錄模式),然后再創(chuàng)建debug目錄(很繞,直接看下圖就會明白了)。


AndroidManifest.xml文件內(nèi)容可以這樣寫

<?xml version="1.0"?encoding="utf-8"?>

<manifest?xmlns:android="http://schemas.android.com/apk/res/android"

package="com.zhuang.home">

<application

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:roundIcon="@mipmap/ic_launcher_round"

android:supportsRtl="true"

android:theme="@style/AppTheme">

</application>

</manifest>


以上內(nèi)容會有很多錯誤提示,其實提示的無非就是資源找不到,我們只需要把這些資源給加上就好了??梢园裮ain組件中相應(yīng)的資源拷貝過來,放在對應(yīng)的目錄下就可以了。

??接下來在home組件的build.gradle文件中,指定不同模式下的AndroidManifest.xml文件。


sourceSets {


main {


if?(isDebug.toBoolean()) {


manifest.srcFile?'src/main/AndroidManifest.xml'


}


}


}



以上設(shè)置完成,并且sync project之后,home組件會是這樣的目錄


??并且android studio的運行app里面,多了一個可運行的app,就是home。



由于我們home組件集成到main組件中時,是以一個fragment界面集成上去的,所以我們的home組件中,沒有一個MainActivity可以作為LaunchActivity,我們可以創(chuàng)建一個,然后把fragment在MainActivity的layout? xml文件中放進去就可以了。


??所對應(yīng)的activity_main.xml布局文件如下


<?xml version="1.0"?encoding="utf-8"?>


<fragment?xmlns:android="http://schemas.android.com/apk/res/android"


android:name="com.zhuang.home.HomeMainFragment"

android:layout_width="match_parent"


android:layout_height="match_parent">


</fragment>


以上步驟完成之后,home就可以單獨作為一個app來開發(fā)了,我們可以直接運行該組件。


共用資源的引用

實際項目中,總有一些資源需要共用,例如第三方庫、自定義的工具類、自定義的view等等,甚至我們的theme。那么這些資源在“組件化”中,應(yīng)該如何處理?每個組件都各自引入?

??如果每個組件都各自引入這些共用資源,一方面效率差,如果一個類是所有組件都用到的,那么就得每個組件中都新增這個類,一旦這個類修改了,還得一個組件一個組件的來修改這個類;另一方面,第三方類庫也有可能會沖突,例如不同組件引用了相同的第三方庫,但是版本不一樣,就沖突了。所以,我們得用另外的方式來處理。

??解決的辦法就是,也把共用庫組件化,然后其他組件引用它,所以我們的架構(gòu)可以演化為這樣:


在項目里面把這個共用庫加上


??然后可以把其他第三方庫、自定義view、工具類、公用資源放進該組件。例如網(wǎng)絡(luò)請求框架retrofit,在common的build.gradle文件中:


然后其他組件,都分別引用common組件,在其他組件對應(yīng)的build.gradle文件中



這樣就可以使用common組件的資源了。

其實我們還可以更簡化,每一個組件的build.gradle所引入的資源,其實有很多是重復(fù)的,我們一樣可以把這些一并加到common組件中去,例如下面這一段,就是所有組件都有的



所以這一部分,也可以放到common里面去。所以三大業(yè)務(wù)組件里面的build.gradle文件就變成這樣:



除了第三方庫,還有自定義的工具類、自定義的view等等這些,就直接在common中編寫java文件就行啊,其他組件能夠引入這些類的。

??還有就是圖片、xml這些(value目錄下的各種xml文件),也是可以一樣被其他組件引用,這里需要特別注意的是style.xml文件,對于全局共用的style,我們應(yīng)該把它也放在common中。例如我們的項目theme,本來是放在main組件的style里面,我們可以把它移到common中,這樣其他組件調(diào)試時,作為一個單獨的項目,也能和主項目有一樣的主題。

??總之就是,所有你認為可以被各個組件共享的資源,都可以放在common組件中。


資源沖突

多組件集成時,其資源文件會被歸檔到一起,所以如果命名重復(fù),那么就會發(fā)生沖突,導(dǎo)致界面混亂。為了解決這個問題,我們可以讓各個組件中的資源都有一個屬于自己的前綴,例如home組件中的資源,我們可以以home_開通,video組件中的資源,我們可以以video_開頭,這樣就防止了資源沖突。在這里gradle可以幫我們做一點事情,就是讓我們在命名資源文件時,幫我們先加上前綴。例如在home組件的build.gradle文件中,加入

resourcePrefix"home_"

這樣之后我們的xml文件如果沒有以home_為前綴的話,就會報錯。但是這個功能其實很弱,例如xml文件報錯,但是我們運行的時候,依然可以運行,圖片文件不已home_為前綴,也不會報錯,所以,資源沖突的問題,還需要開發(fā)者自己多多注意。


組件之間的通信

??組件雖然可以拆分了,但是當(dāng)他們集成到main組件中,一起工作時,還是需要一定的通信,例如業(yè)務(wù)A需要調(diào)用到業(yè)務(wù)B的一個頁面,甚至進行傳參。但是在“組件化”模式下,業(yè)務(wù)A和業(yè)務(wù)B是完全分開的,在業(yè)務(wù)A的認知里,根本就不存在業(yè)務(wù)B,也無從直接調(diào)用。當(dāng)然,如果要A與B可以直接通信,也是可以的,互相引入就可以,但是這樣的話,項目耦合性太高,架構(gòu)也混亂,會把“組件化”的所有優(yōu)點都一一撇掉。我們應(yīng)該用另外一個方式來處理。

??這里需要引入一個概念----“路由”,就如我們實際訪問網(wǎng)絡(luò)一樣,我們電腦發(fā)送的請求都經(jīng)過路由器轉(zhuǎn)發(fā),在“組件化”中,我們也可以設(shè)置這么一個中轉(zhuǎn)站,來統(tǒng)一處理不同組件之間的調(diào)用關(guān)系。支持我們這一思想有一些比較有名的開源項目,如ARouter、ActivityRouter,通過這些開源項目,我們可以用一個url,由其轉(zhuǎn)發(fā),幫我們調(diào)用其他組件。

ARouter使用:

參考鏈接:

https://mp.weixin.qq.com/s?src=11×tamp=1599552720&ver=2571&signature=msb3wX*txhuX2O57iSYbmyqaE-0QNpTBF3ZNTpEwMhwLIhj0uO9mrZt4KCT4tvT*G9bvLRDzWjkcvrVXBY7r92TlEbV2HNEYuNZRrscIzq4EtP1dvCJAgcjqruNN8Zp4&new=1



統(tǒng)一版本號

各個組件的build.gradle文件中,有很多版本號。



我們可以把這些版本號統(tǒng)一管理起來,免得每次修改都得同時修改多份build.gradle文件,也避免不同的組件使用的版本不一樣,導(dǎo)致沖突。

在項目build.gradle文件中(項目根目錄下的build.gradle文件),定義版本號常量


ext {


compileSdkVersion = 25


buildToolsVersion = "25.0.2"


minSdkVersion = 14


targetSdkVersion = 25


versionCode = 1


versionName = "1.0"


}





然后在各個組件的build.gradle文件中,做這樣的修改


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容