組件化項目部署

組件化項目的意義

組件化,簡單來說,就是將一個APP的業務功能進行拆分,每一個功能都是一個單獨的工程,每個工程都能獨立運行,且只包含自己的業務,最後整個APP由多個拆分出的組件集成而成

組件化開發的優點有以下幾點

  1. 極大提高工程編譯速度
    進行組件化拆分後,每個業務或者功能都是一個單獨的工程,這個單獨的工程可以獨立編譯運行,編譯運行速度快,減少時間成本;
  2. 業務模塊解耦,利於多人團隊協作開發,提高團隊開發效率
    業務組件之間不能相互引用,每個組件都把對應的業務功能放在一個工程裏去實現,彼此互不打擾。 在團隊開發中,每個人只負責自己的業務模塊,便於開發測試;
  3. 提高功能重用性
    不同的組件實現的業務功能不同,可以像搭積木一樣任意排列形成新的APP

組件化架構設計圖
在這裏插入圖片描述

phone module 和 Android Library 的區別

phone module: 新建出可以獨立運行的模塊,與創建項目時自動創建的app module 是一樣的,在build.gradle中 是 apply plugin: ‘com.android.application’ ,android 配置下包含applicationId;
Android Library: 新建出的Android庫,不能直接運行,可被其他module引用,在build.gradle 中,是library “apply plugin: ‘com.android.library’”,Android配置下不包含applicationId.

Gradle搭建組件化項目環境

爲了使多個模塊之間配置一致,則可以通過引入統一配置文件進行配置,配置過程如下:

  1. 在工程中創建config.gradle文件 在這裏插入圖片描述
  2. 在文件中設置統一配置內容
// 必須在ext標籤下進行配置
ext {
   	// 標記是測試版本還是正式發佈版本,在模塊中可以根據這個值進行不同的配置
    isRelease = true
 	//相關編譯環境的版本配置
    androidId = [
            compileSdkVersion: 28,
            buildToolsVersion :"29.0.0",
            minSdkVersion : 21,
            targetSdkVersion : 28,
            versionCode: 1,
            versionName :"1.0"
    ]
	//不同模塊的applicationId
    appId = [
            app   : "com.example.zhangzd.zujiandemo",
            order: "com.example.zhangzd.order",
            personal: "com.example.zhangzd.personal"
    ]

	//support包的版本
    supportLibrary = "28.0.0"
    //第三方依賴配置
    dependencies = [
            // ${supportLibrary}表示引用一個變量
            "appcompat"      : "com.android.support:appcompat-v7:${supportLibrary}",
            "recyclerview": "com.android.support:recyclerview-v7:${supportLibrary}",
            "constraint"     : "com.android.support.constraint:constraint-layout:1.1.3",
            "okhttp3"        : "com.squareup.okhttp3:okhttp:3.10.0",
            "retrofit"       : "com.squareup.retrofit2:retrofit:2.5.0",
            "fastjson"       : "com.alibaba:fastjson:1.2.58",
    ]
}
  1. 在工程的build.gradle 中,通過 apply from : “config.gradle” 引入配置文件;
  2. 在模塊的build.gradle中應用配置文件,以APP模塊爲例,配置文件如下
apply plugin: 'com.android.application'
//定義變量androidId等,引入配置文件中的配置信息,
def androidId = rootProject.ext.androidId
def appId = rootProject.ext.androidId
def support = rootProject.ext.dependencies

android {
	// 通過創建的變量配置具體的信息
    compileSdkVersion androidId.compileSdkVersion
    buildToolsVersion androidId.buildToolsVersion
    defaultConfig {
        applicationId appId.app
        minSdkVersion androidId.minSdkVersion
        targetSdkVersion androidId.targetSdkVersion
        versionCode androidId.versionCode
        versionName androidId.versionName

        // 這個方法接收三個非空的參數,第一個:確定值的類型,第二個:指定key的名字,第三個:傳值(必須是String)
        // 爲什麼需要定義這個?因爲src代碼中有可能需要用到跨模塊交互,如果是組件化模塊顯然不行
        // 切記:不能在android根節點,只能在defaultConfig或buildTypes節點下
        buildConfigField("boolean", "isRelease", String.valueOf(isRelease))
        multiDexEnabled false
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // 循環添加第三方依賴,最簡單的方式,可以不循環一個一個添加
    support.each{ k, v ->
        implementation v
    }

    if (isRelease) {
        implementation project(":order")
        implementation project(":personal")
    }
}

集成化模式開發、組件化模式開發

集成化模式開發:即模塊是APP的組成部分,所有的模塊組裝起來便是一個完整的APP,在項目中的表現形式是,在一個工程中,只有一個phone module ,其他的只能作爲Android 的library被引用,只能運行phone module ,其他模塊不能直接運行。例如在一個APP中,首先由主模塊(phone module)app模塊,其次是Oder和Personal兩個library,具體如下圖
在這裏插入圖片描述
組件化模式開發:即每個模塊都是一個phone module ,可以單獨運行,單獨調試。例如,除了app模塊外,Order和Personal 都是phone module,可以單獨運行,如圖
在這裏插入圖片描述
在團隊開發過程中,每個成員可能只開發一個功能模塊,不同的人開發不同功能模塊,此時需要組件化開發模式,每個模塊都是一個單獨的phone module,可以進行單獨運行和測試,加快開發速度。當打包上線時,需要將所有的功能模塊與主模塊一同打包成一個APP,此時需要組件化開發模式,因此需要兩種模式的靈活轉換,我們也可以通過gradle 的配置實現靈活轉換。要進行切換,就需要知道phone module 和Android library的區別,即上邊介紹的兩個區別。因此兩種模式的切換,即非主模塊phone module 和Android library的切換。步驟如下:

  1. config.gradle 配置文件中添加 isRelease = false ,該變量標識是否是測試環境還是正式打包環境;
  2. 在非主模塊中進行如下配置,以order爲例:
//通過定義的isRelease 變量,判斷此時是否是測試環境嗎,測試環境需要切換爲組件化開發模式,即每個模塊都是可以單獨運行的
if (isRelease) {
	// 是release時 ,將module設置爲library
    apply plugin: 'com.android.library'
}else {
	// 不是是release時 ,將module設置爲application
    apply plugin: 'com.android.application'
}

def androidId = rootProject.ext.androidId
def appId = rootProject.ext.androidId
def support = rootProject.ext.dependencies

android {
    compileSdkVersion androidId.compileSdkVersion
    buildToolsVersion androidId.buildToolsVersion
    defaultConfig {
        //發佈版本時沒有applicationID
        if (!isRelease) {
            applicationId appId.order
        }
        minSdkVersion androidId.minSdkVersion
        targetSdkVersion androidId.targetSdkVersion
        versionCode androidId.versionCode
        versionName androidId.versionName
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    support.each{k,v ->
        implementation v
    }
}

  1. 在主模塊中,配置當非release模式下,不引用order等模塊,當release模式時,引用
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    support.each{k,v ->
        implementation v
    }
	//  release 時才進行依賴
    if (isRelease) {
        implementation project(":order")
        implementation project(":personal")
    }
}

經過以上的配置,我們只需要在config.gradle 中更改isRelease變量,即可進行兩種模式的自由切換。
在這裏插入圖片描述

組件化開發時的臨時代碼,集成化打包時動態隔離

當我們切換到集成開發模式並打包成一個Apk時,會發現一個問題,那就是在非主模塊,我們的一些測試文件,比方說mainActivity等,只是在測試時纔會用到,打包時不需要打包到apk,這個需要怎麼解決呢?
在這裏插入圖片描述
我們可以通過配置sourceSet設置資源路徑來解決這個問題

  1. 在非主模塊的main路徑下,新建debug路徑,該路徑下創建測試環境時的AndroidManifest.xml文件;
  2. 在Java.xxx.xxx.xxx.下創建debug,該路徑下存放測試的Java代碼
    在這裏插入圖片描述
  3. 在該模塊的build.gradle中配置sourceSet
if (isRelease) {
    apply plugin: 'com.android.library'
} else {
    apply plugin: 'com.android.application'
}

def androidId = rootProject.ext.androidId
def appId = rootProject.ext.androidId
def support = rootProject.ext.dependencies

android {
    compileSdkVersion androidId.compileSdkVersion
    buildToolsVersion androidId.buildToolsVersion
    defaultConfig {
        //發佈版本時沒有applicationID
        if (!isRelease) {
            applicationId appId.order
        }
        minSdkVersion androidId.minSdkVersion
        targetSdkVersion androidId.targetSdkVersion
        versionCode androidId.versionCode
        versionName androidId.versionName
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    // 配置資源路徑,方便測試環境中的內容不會被打包到apk中去
    sourceSets {
        main{
            if (isRelease) {
                //集成化模式,整個項目打包成一個apk
                manifest.srcFile 'src/main/AndroidManifest.xml'
                java {
                    // debug 目錄下的文件不需要打包到apk中去
                    exclude '**/debug/**'
                }
            }else {
                //組件化模式,需要單獨運行
                manifest.srcFile 'src/main/debug/AndroidManifest.xml'
            }
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    support.each { k, v ->
        implementation v
    }
}

  1. 重新編譯打包,就可以了
    最後查看apk ,打出的apk中不包含測試用的A,B等類
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章