前言
做安卓開發的同學,或多或少都聽過組件化,插件化,熱修復等一系列的熱門技術,他們是什么呢,今天咱們來聊聊組件化開發以及怎么實現組件化開發
什么是組件化
組件化,又叫模塊化,顧名思義就是將一個app拆成多個模塊的組合,每個模塊相當于一個app,可以單獨運行,測試,當我們在開發之中,我們可以讓每個模塊做出一個單獨的app,方便測試以及開發,完成之后,再將app轉成lib,嵌入到主app中,這種模式就是組件化開發,為什么需要組件化開發?這種模式比較適合較大的項目工程,大的項目都是通過合作的方式開發完成,并不是獨立開發,因此,每個人負責不同的模塊,到最后才合并到主工程,可以大大減少開發時間,耦合度,方便測試等好處,我們來看看一幅圖
這幅圖可以很清楚的看到我們的app工程結構,下面來看看怎么創建一個組件化工程,先看下工程結構
可以看到,包含了3個module:
1.base是我們共用的依賴:BaseActivity,BaseFragment,BaseApplication等
2.style是我們的項目的樣式,為了單個module和主app的樣式一致,我們把它抽取出來
3.test是我們測試的業務module
這就是我們整個架構,這里需要注意的幾個點
1.如何確定在開發的時候,module作為app運行,打包的時候作為lib依賴
2.module和app之間的入口activity以及application是如何處理
3.不同模塊之間的activity或者fragment是如何通訊以及數據交互
下面開始飆車
組件化開發
上面我們說過,每個業務組件都可以當成單個app運行,打包的時候才作為lib依賴,所以我們需要去控制組件什么時候是application,什么時候是lib,所以,我們就需要在組件的build.gradle配置兩個屬性
//該屬性可以當成app運行
apply plugin: ‘com.android.application’
//該屬性是lib
apply plugin: ‘com.android.library’
當然,如果不需要當成app運行的話,就不需要配置了,另外,我們可以到gradle.properties去設置一個開關,決定組件什么時候是application,什么時候是lib
# 每次更改“isModule”的值后,需要點擊 "Sync Project" 按鈕
# 在tools-->android-->Sync Project with Gradle Files
# true:application模式 , flase:library模式
isModule=false
然后我們就可以在需要轉換的組件的build.gradle中設置了
if (isModule.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
開發的時候將isModule改成true,打包的時候改成false,這就解決了我們第一個問題
第二個問題,我們知道,每個app都只有一個application,那么,當我們的組件是app的時候需要給它一個application,當是lib的時候,則不能給它application,這其實跟上面的問題很類似,我們可以通過判斷是哪種模式,然后加載哪個AndroidMainfest配置,所以,我們需要創建兩個AndroidMainfest文件,一個是有application,一個是沒有application,我們在main下面創建一個文件夾debug,這個是存放有application的AndroidMainfest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.designpattern.modulea">
<application
android:allowBackup="true"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:name="com.designpattern.module_base.BaseApplication"
android:supportsRtl="true">
<activity
android:name=".ModuleActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
而系統的AndroidMainfest則是這樣:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.designpattern.modulea">
<application android:theme="@style/AppTheme">
<activity android:name=".ModuleActivity" />
</application>
</manifest>
然后我們在build.gradle中配置:
android {
...
//application模式下,加載debug/AndroidManifest.xml
//library模式下,加載src/main/AndroidManifest.xml
sourceSets {
main {
if (isModule.toBoolean()) {
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
}
}
這樣就完成了區分,這里說個小技巧,當我們在開發組件的時候,難免會有些測試類,我們可以把測試的類全部放到debug文件夾中,當我們打包的時候,不加載debug文件夾中的文件即可,這樣省去了刪掉的麻煩,也可以不增加體積
sourceSets {
main {
if (isModule.toBoolean()) {
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
//集成開發模式下排除debug文件夾中的所有Java文件
java {
exclude 'debug/**'
}
}
}
}
現在我們來說說不同模塊的activity交互,我們知道,不同的模塊之間是不能交互的,因為每個module都是獨立的,因此,我們需要依賴需要交互的module,在build.gradle中引入,這里以app的build.gradle為例
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
//application模式引入其他組件,lib模式下引入業務組件
if (isModule.toBoolean()) {
compile project(':module_base')
}else {
compile project(':module_test')
}
}
因為如果是正在開發的時候,我們是不需要引入業務組件的,只用當開發完成,打包的時候才需要引入業務組件,引入了業務組件,我們就可以讓activity進行交互了,但是我們不能直接用Intent的顯式去交互,所以,我們需要用隱式的方式交互,我們需要在module_base中創建一個記錄所有activity的類,命名叫:AppConfig
AppConfig
public class AppConfig {
public static final String MODULE_ACTIVITY="com.designpattern.modulea.ModuleActivity";
}
然后就可以通過隱式的方式進行交互了
Intent intent = new Intent();
intent.setClassName(context,AppConfig.MODULE_ACTIVITY);
startActivity(intent);
當然,還有很多種方式,也有第三方的Router可以交互,這個看個人喜歡,這篇是組件化開發的簡單入門,日后的坑還多,還得慢慢填~~